{"id":"advancedClassMethods/advancedClassMethods_inherited_dispatcher.ek9","url":"https://ek9.io/examples/advancedClassMethods/advancedClassMethods_inherited_dispatcher.html","title":"A sub-class adding a handler to a dispatcher it inherits","code":"#!ek9\ndefines module site.advancedClassMethods.inheritedDispatcher\n\n  defines class\n\n    Shape as open\n      shapeName() as pure\n        <- rtn as String: \"shape\"\n\n    Circle extends Shape\n      override shapeName() as pure\n        <- rtn as String: \"circle\"\n\n    Triangle extends Shape\n      override shapeName() as pure\n        <- rtn as String: \"triangle\"\n\n    Base as open\n      render() as dispatcher\n        -> shape as Shape\n        <- rtn as String: `fallback ${shape.shapeName()}`\n\n      render()\n        -> circle as Circle\n        <- rtn as String: `base ${circle.shapeName()}`\n\n    Sub extends Base\n      render()                              //a new handler - no 'override'\n        -> triangle as Triangle\n        <- rtn as String: `sub ${triangle.shapeName()}`\n\n  defines program\n\n    Rendering()\n      stdout <- Stdout()\n      renderer as Base: Sub()\n      stdout.println(renderer.render(Circle()))     //base circle\n      stdout.println(renderer.render(Triangle()))   //sub triangle\n      stdout.println(renderer.render(Shape()))      //fallback shape","expectedOutput":"base circle\nsub triangle\nfallback shape\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"advancedClassMethods/advancedClassMethods_intersector.ek9","url":"https://ek9.io/examples/advancedClassMethods/advancedClassMethods_intersector.html","title":"Dispatcher methods choosing on the runtime types of their arguments","code":"#!ek9\ndefines module site.advancedClassMethods.intersector\n\n  defines trait\n\n    T1 allow only Square\n      specialMessage() as pure\n        <- rtn as String: \"T1\"\n    T2\n      simpleMessage() as pure\n        <- rtn as String: \"T2\"\n\n  defines function\n\n    intersectSquares() as pure\n      ->\n        s1 as Square\n        s2 as Square\n      <-\n        intersection as Intersection?\n      require s1? and s2?\n      intersection: LinesIntersection(\"Line Intersection two squares (by function)\")\n\n    intersectSquareAndRectangle() as pure\n      ->\n        s1 as Square\n        s2 as Rectangle\n      <-\n        intersection as Intersection?\n      require s1? and s2?\n      intersection: LinesIntersection(\"Line Intersection of a Square and Rectangle (by function)\")\n\n  defines class\n\n    Coordinate\n      x <- Float()\n      y <- Float()\n\n      //Constructor\n      Coordinate() as pure\n        this(0.0, 0.0)\n\n      //Constructor\n      Coordinate() as pure\n        ->\n          initialX as Float\n          initialY as Float\n\n        require initialX? and initialY?\n        x:=? Float(initialX)\n        y:=? Float(initialY)\n\n      x() as pure\n        <- rtn as Float: Float(x)\n      y() as pure\n        <- rtn as Float: Float(y)\n\n      operator $ as pure\n        <- rtn as String: `${$x}, ${$y}`\n      operator #^ as pure\n        <- rtn as String: $this\n\n      default operator ?\n\n    //Used for different types of intersection\n\n    Intersection as open\n      message <- String()\n      stdout as Stdout: Stdout()\n      startPoint Coordinate: Coordinate(0.0, 0.0)\n\n      Intersection() as pure\n        -> message as String\n        this.message:=? String(message)\n\n      render()\n        stdout.println(message)\n\n      default operator ?\n\n      //... Other methods\n\n    ArcIntersection is Intersection\n      endPoint Coordinate: Coordinate()\n      centrePoint Coordinate: Coordinate()\n\n      ArcIntersection() as pure\n        -> message as String\n        super(message)\n\n      default operator ?\n\n      //... Other methods\n\n    LinesIntersection is Intersection\n      endPoint Coordinate: Coordinate()\n      secondLineEnd Coordinate: Coordinate()\n\n      LinesIntersection() as pure\n        -> message as String\n        super(message)\n\n      default operator ?\n\n      //... Other methods\n\n    Shape as abstract\n      stdout as Stdout: Stdout()\n\n      draw() as abstract\n\n      protected draw()\n        -> message as String\n        stdout.println(\"DRAW: \" + message)\n\n      default operator ?\n\n    Ellipse extends Shape as open\n      override draw()\n        draw(\"Ellipse\")\n\n    Circle is Ellipse\n      override draw()\n        draw(\"Circle\")\n\n    Rectangle is Shape\n      override draw()\n        draw(\"Rectangle\")\n\n    Triangle is Shape\n      override draw()\n        draw(\"Triangle\")\n\n    Square is Shape with trait of T1, T2\n      override draw()\n        draw(`Square ${T1.specialMessage()} ${T2.simpleMessage()}`)\n\n      default operator ?\n\n    BaseIntersector as abstract\n      intersect() as pure abstract\n        ->\n          s1 as Shape\n          s2 as Shape\n        <-\n          intersection as Intersection?\n\n      intersect() as pure\n        ->\n          s1 as Circle\n          s2 as Circle\n        <-\n          intersection as Intersection?\n        require s1? and s2?\n        intersection: ArcIntersection(\"Arc Intersection two circles\")\n\n      intersect() as pure\n        ->\n          s1 as Circle\n          s2 as Ellipse\n        <-\n          intersection as Intersection?\n        require s1? and s2?\n        intersection: ArcIntersection(\"Arc Intersection circle and ellipse\")\n\n      intersect() as pure\n        ->\n          s1 as Ellipse\n          s2 as Circle\n        <-\n          intersection as Intersection?\n        require s1? and s2?\n        intersection: ArcIntersection(\"Arc Intersection ellipse and circle\")\n      intersect() as pure\n        ->\n          s1 as Circle\n          s2 as Rectangle\n        <-\n          intersection as Intersection?\n        require s1? and s2?\n        intersection: ArcIntersection(\"Arc Intersection circle and rectangle\")\n\n      intersect() as pure\n        ->\n          s1 as Rectangle\n          s2 as Circle\n        <-\n          intersection as Intersection?\n        require s1? and s2?\n        intersection: ArcIntersection(\"Arc Intersection rectangle and circle\")\n      intersect() as pure\n        ->\n          s1 as Circle\n          s2 as Square\n        <-\n          intersection as Intersection?\n        require s1? and s2?\n        intersection: ArcIntersection(\"Arc Intersection circle and square\")\n      intersect() as pure\n        ->\n          s1 as Square\n          s2 as Circle\n        <-\n          intersection as Intersection?\n        require s1? and s2?\n        intersection: ArcIntersection(\"Arc Intersection squares and circle\")\n      intersect() as pure\n        ->\n          s1 as Rectangle\n          s2 as Rectangle\n        <-\n          intersection as Intersection?\n        require s1? and s2?\n        intersection: LinesIntersection(\"Line Intersection two rectangles\")\n    SpecialIntersector extends BaseIntersector as abstract\n      //Adding another method with additional types of shapes\n      //But still this is an abstract class\n\n      intersect() as pure\n        ->\n          s1 as Ellipse\n          s2 as Triangle\n        <-\n          intersection as Intersection?\n        require s1? and s2?\n        intersection: LinesIntersection(\"Line Intersection ellipse and rectangle\")\n\n      intersect() as pure\n        ->\n          s1 as Circle\n          s2 as Triangle\n        <-\n          intersection as Intersection?\n        require s1? and s2?\n        intersection: LinesIntersection(\"Line Intersection circle and triangle\")\n\n      intersect() as pure\n        ->\n          s1 as Triangle\n          s2 as Triangle\n        <-\n          intersection as Intersection?\n        require s1? and s2?\n        intersection: LinesIntersection(\"Line Intersection two triangles\")\n\n      //Methods that just delegate to functions for the calculations.\n      intersect() as pure\n        ->\n          s1 as Square\n          s2 as Square\n        <-\n          intersection as Intersection: intersectSquares(s1, s2)\n\n      intersect() as pure\n        ->\n          s1 as Square\n          s2 as Rectangle\n        <-\n          intersection as Intersection: intersectSquareAndRectangle(s1, s2)\n\n      intersect() as pure\n        ->\n          s1 as Rectangle\n          s2 as Square\n        <-\n          intersection as Intersection: intersectSquareAndRectangle(s2, s1)\n\n    //Finally make a concrete one - override the base intersect method that was abstract and mark it as a dispatcher\n    Intersector extends SpecialIntersector\n      override intersect() as pure dispatcher\n        ->\n          s1 as Shape\n          s2 as Shape\n        <-\n          intersection as Intersection: Intersection(\"Intersection just two shapes!\")\n\n    Renderer\n\n      //entry point for rendering via defining the dispatcher - this will find all sub type methods can call render\n      render() as dispatcher\n        -> s as Shape\n        s.draw()\n\n      //Just use default method for Circle and Ellipse, but others does something slight different\n\n      render()\n        -> s as Triangle\n        s.draw()\n        Stdout().println(\"Did draw triangle\")\n\n      render()\n        -> s as Rectangle\n        Stdout().println(\"Will Draw Rectangle\")\n        s.draw()\n\n      render()\n        -> s as T1\n        Stdout().println(\"Drawing: \" + s.specialMessage())\n\n      render()\n        -> s as T2\n        Stdout().println(\"Drawing: \" + s.simpleMessage())\n\n      //With Square also implementing T1 and T2 you have to add this in. Which is correct else ambiguous.\n      render()\n        -> s as Square\n        Stdout().println(\"Before Square\")\n        s.draw()\n        Stdout().println(\"After Square\")\n\n  defines program\n    testShapes()\n      //Would really need actual details of what the circles and triangles were.\n      //But this is just to show how a dispatcher would work.\n      firstShapes <- [ Circle(), Ellipse(), Rectangle(), Square(), Triangle() ]\n      secondShapes <- [ Circle(), Ellipse(), Rectangle(), Square(), Triangle() ]\n\n      intersector <- Intersector()\n      renderer <- Renderer()\n\n      //Simple imperative loop this time rather than stream pipeline.\n      for s1 in firstShapes\n        for s2 in secondShapes\n          renderer.render(s1)\n          renderer.render(s2)\n          intersection <- intersector.intersect(s1, s2)\n          intersection.render()","expectedOutput":"DRAW: Circle\nDRAW: Circle\nArc Intersection two circles\nDRAW: Circle\nDRAW: Ellipse\nArc Intersection circle and ellipse\nDRAW: Circle\nWill Draw Rectangle\nDRAW: Rectangle\nArc Intersection circle and rectangle\nDRAW: Circle\nBefore Square\nDRAW: Square T1 T2\nAfter Square\nArc Intersection circle and square\nDRAW: Circle\nDRAW: Triangle\nDid draw triangle\nLine Intersection circle and triangle\nDRAW: Ellipse\nDRAW: Circle\nArc Intersection ellipse and circle\nDRAW: Ellipse\nDRAW: Ellipse\nIntersection just two shapes!\nDRAW: Ellipse\nWill Draw Rectangle\nDRAW: Rectangle\nIntersection just two shapes!\nDRAW: Ellipse\nBefore Square\nDRAW: Square T1 T2\nAfter Square\nIntersection just two shapes!\nDRAW: Ellipse\nDRAW: Triangle\nDid draw triangle\nLine Intersection ellipse and rectangle\nWill Draw Rectangle\nDRAW: Rectangle\nDRAW: Circle\nArc Intersection rectangle and circle\nWill Draw Rectangle\nDRAW: Rectangle\nDRAW: Ellipse\nIntersection just two shapes!\nWill Draw Rectangle\nDRAW: Rectangle\nWill Draw Rectangle\nDRAW: Rectangle\nLine Intersection two rectangles\nWill Draw Rectangle\nDRAW: Rectangle\nBefore Square\nDRAW: Square T1 T2\nAfter Square\nLine Intersection of a Square and Rectangle (by function)\nWill Draw Rectangle\nDRAW: Rectangle\nDRAW: Triangle\nDid draw triangle\nIntersection just two shapes!\nBefore Square\nDRAW: Square T1 T2\nAfter Square\nDRAW: Circle\nArc Intersection squares and circle\nBefore Square\nDRAW: Square T1 T2\nAfter Square\nDRAW: Ellipse\nIntersection just two shapes!\nBefore Square\nDRAW: Square T1 T2\nAfter Square\nWill Draw Rectangle\nDRAW: Rectangle\nLine Intersection of a Square and Rectangle (by function)\nBefore Square\nDRAW: Square T1 T2\nAfter Square\nBefore Square\nDRAW: Square T1 T2\nAfter Square\nLine Intersection two squares (by function)\nBefore Square\nDRAW: Square T1 T2\nAfter Square\nDRAW: Triangle\nDid draw triangle\nIntersection just two shapes!\nDRAW: Triangle\nDid draw triangle\nDRAW: Circle\nIntersection just two shapes!\nDRAW: Triangle\nDid draw triangle\nDRAW: Ellipse\nIntersection just two shapes!\nDRAW: Triangle\nDid draw triangle\nWill Draw Rectangle\nDRAW: Rectangle\nIntersection just two shapes!\nDRAW: Triangle\nDid draw triangle\nBefore Square\nDRAW: Square T1 T2\nAfter Square\nIntersection just two shapes!\nDRAW: Triangle\nDid draw triangle\nDRAW: Triangle\nDid draw triangle\nLine Intersection two triangles\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"basics/basics_areas.ek9","url":"https://ek9.io/examples/basics/basics_areas.html","title":"Using a constant from another module through references","code":"#!ek9\ndefines module site.basics.areas\n  references\n    site.basics.geometry::PI\n\n  defines function\n    areaOfCircle()\n      -> diameter as Float\n      <- result as Float: PI * (diameter/2)^2","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"basics/basics_areas_qualified.ek9","url":"https://ek9.io/examples/basics/basics_areas_qualified.html","title":"Using a constant from another module by its fully qualified name","code":"#!ek9\ndefines module site.basics.areas.qualified\n  defines function\n    areaOfCircle()\n      -> diameter as Float\n      <- result as Float: site.basics.geometry::PI * (diameter/2)^2","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"basics/basics_geometry.ek9","url":"https://ek9.io/examples/basics/basics_geometry.html","title":"A constant in its own module","code":"#!ek9\ndefines module site.basics.geometry\n  defines constant\n    PI <- 3.142","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"basics/basics_parameters.ek9","url":"https://ek9.io/examples/basics/basics_parameters.html","title":"Accepting and returning parameters","code":"#!ek9\ndefines module site.basics.parameters\n\n  defines function\n\n    function1()\n      -> n as Integer\n      <- sum as Integer: n + n\n\n    function2()\n      ->\n        n1 as Integer\n        n2 as Integer\n      <-\n        sum as Integer: n1 + n2","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"basics/basics_pure.ek9","url":"https://ek9.io/examples/basics/basics_pure.html","title":"A pure function, as a loop and as a stream","code":"#!ek9\ndefines module site.basics.pure\n\n  defines function\n\n    <?-\n      Just sums the squares of values from 1 to n.\n    -?>\n    sumOfSquares() as pure\n      -> n as Integer\n      <- sum as Integer: 0\n      for i in 1 ... n\n        sum: sum + i*i\n\n    //An alternative solution using stream pipeline\n\n    <?-\n      Square of number.\n    -?>\n    square() as pure\n      -> number as Integer\n      <- squared as Integer: number * number\n\n    streamingSumOfSquares() as pure\n      -> n as Integer\n      <- sum as Integer: for i in 1 ... n | map with square | collect as Integer\n\n  defines program\n\n    ShowSumOfSquares()\n      stdout <- Stdout()\n      stdout.println(`Loop: ${sumOfSquares(10)}, stream: ${streamingSumOfSquares(10)}`)","expectedOutput":"Loop: 385, stream: 385\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"basics/basics_pure_reassign.ek9","url":"https://ek9.io/examples/basics/basics_pure_reassign.html","title":"Reassigning a variable in a pure function","code":"#!ek9\ndefines module bad.site.basics.purereassign\n\n  defines function\n\n    sumOfSquares() as pure\n      -> n as Integer\n      <- sum as Integer: 0\n      limit <- n\n      limit := 20\n      for i in 1 ... limit\n        sum: sum + i*i","expectedOutput":null,"kind":"bad","errors":["E08100"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"basics/basics_sanitized.ek9","url":"https://ek9.io/examples/basics/basics_sanitized.html","title":"Sanitized parameters","code":"#!ek9\ndefines module site.basics.sanitized\n\n  defines function\n\n    executeQuery()\n      -> sql as sanitized String\n      <- result as String: `Executing: ${sql}`\n      //The 'sql' parameter is automatically sanitized on entry,\n      //before any of this function's code runs - preventing SQL injection\n\n    processUserInput()\n      ->\n        name as sanitized String\n        comment as sanitized String\n      <- success as Boolean: name? and comment?\n      //Both parameters are sanitized before use","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"basics/basics_sanitized_alias.ek9","url":"https://ek9.io/examples/basics/basics_sanitized_alias.html","title":"Assigning a sanitized parameter to a local","code":"#!ek9\ndefines module bad.site.basics.sanitizedalias\n\n  defines function\n\n    //Creates a hidden alias\n    processInput()\n      -> input as sanitized String\n      <- result as String: String()\n      local <- input      // 'local' would be an alias to 'input'\n      local += \" modified\" // would also modify 'input'!\n      result: local","expectedOutput":null,"kind":"bad","errors":["E07930"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"basics/basics_sanitized_copy.ek9","url":"https://ek9.io/examples/basics/basics_sanitized_copy.html","title":"An explicit copy of a sanitized parameter","code":"#!ek9\ndefines module site.basics.sanitizedcopy\n\n  defines function\n\n    //An explicit copy\n    processInput()\n      -> input as sanitized String\n      <- result as String: String()\n      local <- String(input)  // OK: Explicit copy constructor\n      local += \" modified\"     // Only affects 'local'\n      result: local","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"basics/basics_tristate.ek9","url":"https://ek9.io/examples/basics/basics_tristate.html","title":"Unset, set and the guard","code":"#!ek9\ndefines module site.basics.tristate\n\n  defines record\n\n    User\n      name <- String()\n\n      User()\n        -> name as String\n        this.name: name\n\n      default User()\n\n      default operator ?\n\n  defines function\n\n    lookup()\n      ->\n        database as Dict of (Integer, User)\n        id as Integer\n      <- rtn as String: String()\n\n      if user <- database.getOrDefault(id, User())\n        // user is SET: the lookup succeeded, the key was found\n        rtn: `Found ${user.name}`\n      else\n        // user is UNSET (the default was used): the key was not in the database\n        // the guard ensures user is never used unset\n        rtn: `No user with id ${id}`\n\n  defines program\n\n    TriState()\n      stdout <- Stdout()\n\n      database <- {1: User(\"Steve\")}\n      stdout.println(lookup(database, 1))\n      stdout.println(lookup(database, 2))\n\n      name <- String()\n      stdout.println(`name set: ${name?}`)    // false - unset\n\n      name: \"Steve\"\n      stdout.println(`name set: ${name?}`)    // true - set\n\n      items <- List() of String\n      stdout.println(`items set: ${items?}`)  // true - set (empty is valid for collections)\n\n      items += \"first\"\n      stdout.println(`items set: ${items?}`)  // true - still set (now has 1 item)","expectedOutput":"Found Steve\nNo user with id 2\nname set: false\nname set: true\nitems set: true\nitems set: true\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"basics/basics_variables.ek9","url":"https://ek9.io/examples/basics/basics_variables.html","title":"Declaring and assigning variables","code":"#!ek9\ndefines module site.basics.variables\n\n  defines function\n\n    inferredDeclaration()\n      stdout <- Stdout()\n\n      //Declare an Integer - but with no value yet known.\n      age <- Integer()\n      //Declare an Integer - but with a known value from the outset.\n      minimumAge <- 21\n\n      stdout.println(`${age?} ${minimumAge}`)\n\n    explicitDeclaration()\n      stdout <- Stdout()\n\n      //Declare an Integer - but with no value yet known.\n      age as Integer: Integer()\n      //Or like this.\n      ageAgain as Integer = Integer()\n      //Or even like this.\n      ageOnceMore as Integer := Integer()\n      //Declare an Integer - without type inference\n      minimumAge as Integer := 21\n\n      stdout.println(`${age?} ${ageAgain?} ${ageOnceMore?} ${minimumAge}`)\n\n    laterAssignedDeclaration()\n      stdout <- Stdout()\n\n      //Declare an Integer - but no space allocated\n      possibleError as Integer?\n\n      possibleError: 42\n      stdout.println(possibleError)\n\n    preferredForms()\n      stdout <- Stdout()\n\n      minimumAge <- 21\n      //Alternatively - which can be useful\n      minimumAgeTyped as Integer: 21\n\n      stdout.println(`${minimumAge} ${minimumAgeTyped}`)\n\n    unsetIsNotExecuted()\n      stdout <- Stdout()\n\n      age <- Integer()\n      if age?\n        //This block would not be executed\n        stdout.println(\"age is set\")\n      else\n        //This block would be the section that is executed\n        stdout.println(\"age is not set\")\n\n    collectionIsSet()\n      stdout <- Stdout()\n\n      //A simple empty list\n      aList as List of Integer := List()\n      if aList?\n        //Code where aList has some meaningful value/content\n        stdout.println(\"aList is set, even though it is empty\")\n\n      //A list with some values using the 'list shorthand of' [] - this not an array!\n      bList <- [ \"A\", \"B\", \"C\" ]\n\n      stdout.println(bList)\n\n    iterating()\n      stdout <- Stdout()\n      bList <- [ \"A\", \"B\", \"C\" ]\n      iteratorB <- bList.iterator()\n      while iteratorB?\n        stdout.println(`Value is [${iteratorB.next()}]`)\n\n      //The stream pipeline construct is cleaner though\n      cat bList > stdout\n\n    reassignment()\n      stdout <- Stdout()\n\n      //Declare charges and initialise\n      charges <- 20.99\n      //Use charges for some processing\n      stdout.println(charges)\n      //Now set the same variable to a new value\n      charges := 50.99\n      //Use updated charges for some processing\n\n      stdout.println(charges)\n\n    assignmentForms()\n      stdout <- Stdout()\n\n      //Declare charges and initialise\n      charges <- 20.99\n      stdout.println(charges)\n      charges: 50.99\n      charges = 50.99\n      //Using := 'feels' more significant\n      charges := 50.99\n\n      stdout.println(charges)\n\n    comments()\n      stdout <- Stdout()\n\n      //A one line comment\n      variable <- 21 //Comments can be at the end of a line if necessary\n\n      <!--\n      These lines will be contained\n      within a comment block.\n      -->\n\n      <!-\n      These lines will be contained\n      within a comment block, just like above.\n      -!>\n\n      stdout.println(variable)\n\n    <?-\n    Just sums the squares of values from 1 to n.\n    -?>\n    sumOfSquares()\n      -> n as Integer\n      <- sum as Integer: 0\n      for i in 1 ... n\n        sum += i * i\n\n  defines program\n\n    Variables()\n      inferredDeclaration()\n      explicitDeclaration()\n      laterAssignedDeclaration()\n      preferredForms()\n      unsetIsNotExecuted()\n      collectionIsSet()\n      iterating()\n      reassignment()\n      assignmentForms()\n      comments()\n      Stdout().println(sumOfSquares(3))","expectedOutput":"false 21\nfalse false false 21\n42\n21 21\nage is not set\naList is set, even though it is empty\n[\"A\", \"B\", \"C\"]\nValue is [A]\nValue is [B]\nValue is [C]\nA\nB\nC\n20.99\n50.99\n20.99\n50.99\n21\n14\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_any_list.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_any_list.html","title":"A heterogeneous list of Any","code":"#!ek9\ndefines module site.builtintypes.anylist\n\n  defines type\n    CardSuit\n      Hearts\n      Diamonds\n      Clubs\n      Spades\n\n  defines program\n\n    AnyList()\n      stdout <- Stdout()\n\n      //A heterogeneous list - declare List of Any (an undeclared mix sharing only Any is E50030)\n      mixedList as List of Any: [ 1, \"hello\", 2024-01-15, CardSuit.Hearts ]\n      //To process these, use a dispatcher - see Advanced Class Methods\n\n      stdout.println(length of mixedList)","expectedOutput":"4\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_big_decimal.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_big_decimal.html","title":"BigDecimal arithmetic","code":"#!ek9\ndefines module site.builtInTypes.bigDecimal\n\n  defines program\n\n    BigDecimalExample()\n      stdout <- Stdout()\n\n      total <- BigDecimal(\"0.1\") + BigDecimal(\"0.2\")\n      stdout.println(\"0.1 + 0.2 = \" + $total)","expectedOutput":"0.1 + 0.2 = 0.3\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_big_integer.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_big_integer.html","title":"BigInteger arithmetic","code":"#!ek9\ndefines module site.builtInTypes.bigInteger\n\n  defines program\n\n    BigIntegerExample()\n      stdout <- Stdout()\n\n      //A value far beyond the range of a 64-bit Integer\n      big <- BigInteger(\"123456789012345678901234567890\")\n\n      //Multiplication never overflows\n      squared <- big * big\n      stdout.println(\"Squared is \" + $squared)","expectedOutput":"Squared is 15241578753238836750495351562536198787501905199875019052100\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_bits.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_bits.html","title":"Using Bits","code":"#!ek9\ndefines module site.builtintypes.bits\n\n  defines function\n\n    booleanToBits() as pure\n      -> bitIsSet as Boolean\n      <- rtn as Bits: bitIsSet <- 0b1 else 0b0\n\n    bitsExamples()\n      stdout <- Stdout()\n\n      //Bits values\n      a <- 0b010011\n      b <- 0b101010\n      c <- 0b010011\n\n      //Equality Operators\n      equalAB <- a == b //result would be false\n      notEqualAB <- a <> b //result would be true\n      lessAB <- a < b //result would be true\n      lessOrEqualAB <- a <= b //result would be true\n      greaterAB <- a > b //result would be false\n      greaterOrEqualAB <- a >= b //result would be false\n      equalAC <- a == c //result would be true\n      notEqualAC <- a != c //result would be false\n      alsoNotEqualAC <- a <> c //result would be false (alternate syntax)\n\n      //Joining/Adding Bits\n      set6 <- 0b010011\n      set7 <- 0b101010\n\n      set6set7 <- set6 + set7 //result would be 010011101010\n      set6true <- set6 + true //result would be 0100111\n      set6false <- set6 + false //result would be 0100110\n      set6false += true //set6false would now be 01001101\n\n      //Bitwise operations\n      ored <- set6 or set7 //result would be 0b111011\n      xored <- set6 xor set7 //result would be 0b111001\n      anded <- set6 and set7 //result would be 0b000010\n      notted <- ~set6 //result would be 0b101100\n      alsonotted <- not set6 //result would be 0b101100\n\n      stdout.println(`${equalAB} ${notEqualAB} ${lessAB} ${lessOrEqualAB} ${greaterAB} ${greaterOrEqualAB}`)\n      stdout.println(`${equalAC} ${notEqualAC} ${alsoNotEqualAC}`)\n      stdout.println(`${set6set7} ${set6true} ${set6false}`)\n      stdout.println(`${ored} ${xored} ${anded} ${notted} ${alsonotted}`)\n\n      //Extracting ranges of Bits\n      //assumes function booleanToBits has been defined\n      partial <- cat set6false | skip 3 | map with booleanToBits | collect as Bits\n      //partial has the value of 0b10010\n\n      stdout.println(partial)\n\n  defines program\n\n    BitsUse()\n      bitsExamples()","expectedOutput":"false true true true false false\ntrue false false\n010011101010 0100111 01001101\n111011 111001 000010 101100 101100\n10010\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_boolean.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_boolean.html","title":"Declaring Boolean variables","code":"#!ek9\ndefines module site.builtintypes.boolean\n\n  defines program\n\n    BooleanDeclarations()\n      stdout <- Stdout()\n\n      //Declare a Boolean - using type inference but with no value yet known.\n      reviewAccess <- Boolean()\n      //Declare a Boolean - with type inference with a known initial value\n      allowModification <- false\n      //Declare a Boolean - but with no space allocated to hold the value.\n      provideAccess as Boolean?\n      //Declare a Boolean - but with no value yet known.\n      denyAccess as Boolean: Boolean()\n      //Declare a Boolean - without type inference\n      allowViewing as Boolean := true\n\n      provideAccess: true\n      stdout.println(`${reviewAccess?} ${allowModification} ${provideAccess} ${denyAccess?} ${allowViewing}`)","expectedOutput":"false false true false true\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_byte.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_byte.html","title":"The Byte type","code":"#!ek9\ndefines module site.builtInTypes.byte\n\n  defines program\n\n    ByteExample()\n      stdout <- Stdout()\n\n      //Hex text, an Integer, or a copy\n      fromHex <- Byte(\"0xFF\")\n      fromInteger <- Byte(255)\n\n      //$ always emits two upper-case hex characters, so the round trip holds\n      stdout.println($fromHex)                  //FF\n      stdout.println($Byte(15))                 //0F\n\n      //Out of range is un set, never wrapped\n      stdout.println(`Byte(256) is set: ${Byte(256)?}`)\n\n      //Bitwise, and shifts that stay inside eight bits\n      masked <- Byte(\"AA\") and Byte(\"0F\")       //0A\n      stdout.println($masked)\n      stdout.println($(Byte(\"0F\") << 4))        //F0\n      stdout.println($(Byte(\"0F\") << 8))        //00 - shifted out, not widened\n\n      //Arithmetic is deliberate - and widens rather than wrapping\n      stdout.println(`1 + 0xFF = ${1 + #^fromInteger}`)   //256\n\n      //Conversions\n      stdout.println($fromInteger.toInteger())  //255\n      stdout.println($Byte(\"AA\").toBits())      //10101010","expectedOutput":"FF\n0F\nByte(256) is set: false\n0A\nF0\n00\n1 + 0xFF = 256\n255\n10101010\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_bytes.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_bytes.html","title":"The Bytes type","code":"#!ek9\ndefines module site.builtInTypes.bytes\n\n  defines program\n\n    BytesExample()\n      stdout <- Stdout()\n\n      //Hex in, hex out - the round trip always holds\n      payload <- Bytes(\"DEADBEEF\")\n      stdout.println(`${payload} has ${length payload} bytes`)\n      stdout.println(payload.toBase64())\n\n      //Buffers via the 'with' factory convention\n      mask <- Bytes().withLength(4, Byte(\"FF\"))\n\n      //xor is its own inverse - the workhorse of low level code\n      masked <- payload xor mask\n      stdout.println(`masked ${masked}, recovered ${(masked xor mask) == payload}`)\n\n      //Unequal lengths are un set, never zero extended\n      stdout.println(`short key set: ${(payload xor Bytes(\"FF\"))?}`)\n\n      //'+' concatenates and slices are values, not views\n      stdout.println($(Bytes(\"DEAD\") + Bytes(\"BEEF\")))\n      stdout.println($payload.first(2))\n\n      //Shifts cross byte boundaries and keep the length\n      stdout.println($(payload << 4))\n\n      //Grow to make room, then shift the content into it\n      stdout.println($(Bytes(\"DEAD\").growLeft(2) << 16))","expectedOutput":"DEADBEEF has 4 bytes\n3q2+7w==\nmasked 21524110, recovered true\nshort key set: false\nDEADBEEF\nDEAD\nEADBEEF0\nDEAD0000\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_bytes_builder.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_bytes_builder.html","title":"Building Bytes","code":"#!ek9\ndefines module site.builtInTypes.bytesBuilder\n\n  defines constant\n\n    tlsVersionTls12 <- 0x0303\n    tlsBodyLength <- 8\n\n  defines program\n\n    BytesBuilderExample()\n      stdout <- Stdout()\n\n      //Building the TLS-record shape that the BytesReader example parses. The endianness is in\n      //the method name, so it is visible on the line doing the writing.\n      record <- BytesBuilder()\n      record.append(Byte(\"16\"))\n      record.appendUInt16BE(tlsVersionTls12)\n      record.appendUInt16BE(tlsBodyLength)\n      record.append(Bytes(\"034142430358595a\"))\n      stdout.println(`framed: ${record.toBytes()}`)\n\n      //Big and little endian genuinely differ - there is no defaulted spelling\n      bigEndian <- BytesBuilder()\n      bigEndian.appendUInt32BE(0x01020304)\n      littleEndian <- BytesBuilder()\n      littleEndian.appendUInt32LE(0x01020304)\n      stdout.println(`big ${bigEndian.toBytes()}, little ${littleEndian.toBytes()}`)\n\n      //A number too wide for its field is rejected, never truncated into a quiet lie\n      tooWide <- BytesBuilder()\n      tooWide.appendUInt16BE(0x10000)\n      stdout.println(`too wide accepted: ${tooWide?}`)\n\n      //xorInto is AddRoundKey, the Argon2 block XOR and the ChaCha20 keystream application,\n      //and it is its own inverse\n      block <- BytesBuilder(Bytes(\"ffffffff\"))\n      block.xorInto(0, Bytes(\"0f0f0f0f\"))\n      stdout.println(`after xor: ${block.toBytes()}`)\n\n      //wipe zeroes the backing store and leaves the builder usable - something an immutable\n      //Bytes fundamentally cannot offer\n      secret <- BytesBuilder(Bytes(\"cafebabedeadbeef\"))\n      secret.wipe()\n      stdout.println(`wiped to length ${length secret}, still usable ${secret?}`)","expectedOutput":"framed: 1603030008034142430358595A\nbig 01020304, little 04030201\ntoo wide accepted: false\nafter xor: F0F0F0F0\nwiped to length 0, still usable true\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_bytes_reader.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_bytes_reader.html","title":"Reading values out of Bytes","code":"#!ek9\ndefines module site.builtInTypes.bytesReader\n\n  defines program\n\n    BytesReaderExample()\n      stdout <- Stdout()\n\n      //A TLS-record shape: type, version, body length, then a length-prefixed body\n      record <- Bytes(\"1603030008034142430358595a\")\n      cursor <- record.reader()\n\n      stdout.println(`type ${cursor.readByte()}, version ${cursor.readUInt16BE()}`)\n      bodyLength <- cursor.readUInt16BE()\n\n      //A bounded view - it cannot read past its own boundary\n      body <- cursor.slice(bodyLength)\n      fieldLength <- body.readByte().toInteger()\n      stdout.println(`first field: ${body.readBytes(fieldLength)}`)\n\n      //A short read is un set and does NOT move the cursor\n      short <- Bytes(\"010203\").reader()\n      stdout.println(`wide read set: ${short.readUInt32BE()?}`)\n      stdout.println(`still at ${short.position()}, smaller read gives ${short.readUInt16BE()}`)","expectedOutput":"type 16, version 771\nfirst field: 414243\nwide read set: false\nstill at 0, smaller read gives 258\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_character.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_character.html","title":"Using Character","code":"#!ek9\ndefines module site.builtintypes.character\n\n  defines program\n\n    CharacterUse()\n      stdout <- Stdout()\n\n      //Some examples of using Character, some with type inference\n      c1 <- Character()\n      c2 <- 's'\n      c3 as Character := 'é'\n\n      //Comparisons\n      lessThan <- c1 < c2\n      lessOrEqual <- c1 <= c2\n      greaterThan <- c1 > c2\n      greaterOrEqual <- c1 >= c2\n      equal <- c1 == c2\n      notEqual <- c1 != c2\n      alsoNotEqual <- c1 <> c2\n\n      //Other operators\n      length1 <- length c1 //results in not set\n      length2 <- length c2 //results in 1\n      length3 <- length c3 //results in 1\n\n      length4 <- c3.length() //same result (1) - but written in object form\n      hashCode1 <- #? c3 //results in 233 (hashcode method)\n      hashCode2 <- c3.#?() //same result (233) - but written in object form\n\n      //Promotion to String\n      str1 as String := #^c2 //results String of \"s\"\n      str2 <- #^c2 //also results String of \"s\" - uses type inference\n      str3 <- c2.#^() //also results String of \"s\" - uses type inference and object form\n\n      //Standard methods\n      upper <- c2.upperCase() //results in 'S'\n      lower <- c2.upperCase().lowerCase() //results in 's'\n\n      stdout.println(`${lessThan?} ${lessOrEqual?} ${greaterThan?} ${greaterOrEqual?} ${equal?} ${notEqual?} ${alsoNotEqual?}`)\n      stdout.println(`${length1?} ${length2} ${length3} ${length4} ${hashCode1} ${hashCode2}`)\n      stdout.println(`${str1} ${str2} ${str3} ${upper} ${lower}`)","expectedOutput":"false false false false false false false\nfalse 1 1 1 233 233\ns s s S s\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_colour.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_colour.html","title":"The Colour type","code":"#!ek9\ndefines module site.builtInTypes.colour\n\n  defines program\n\n    ShowSimpleColour()\n\n      //Colour can hold RGB or ARGB (i.e with alpha channel)\n      //Here shown with alpha channel fully opaque\n      testColour <- #FF186276\n      testColourAsBits <- testColour.bits()\n      require testColourAsBits == 0b11111111000110000110001001110110\n\n      //Bitwise manipulation and colour recreation from bits\n      modifiedBits <- testColourAsBits and 0b10110111000100000110001010110110\n      modifiedColour <- Colour(modifiedBits)\n      require modifiedColour == #B7106236\n      require modifiedBits == 0b10110111000100000110001000110110\n\n      //Note it is also possible to access the HSL values of the colour\n      require modifiedColour.hue() == 148\n      require modifiedColour.saturation() == 71.9298245614035\n      require modifiedColour.lightness() == 22.35294117647059\n\n      //Alter the alpha channel to control how transparent/opaque\n      moreOpaqueColour <- modifiedColour.withOpaque(80)\n      require moreOpaqueColour == #CC106236\n\n      //It can be made lighter - much lighter in this case\n      lighterColour <- moreOpaqueColour.withLightness(80)\n      require lighterColour == #CCA7F1CA\n\n      //Then we can saturate it more\n      moreSaturatedColour <- lighterColour.withSaturation(90)\n      require moreSaturatedColour == #CC9EFAC9\n\n      //Remove some Red from this colour: '-' clears the bits given (#9E with #3A cleared is #84)\n      lessRedColour <- moreSaturatedColour - #3A0000\n      require lessRedColour == #CC84FAC9\n\n      //Add in some blue: '+' sets the bits given (#C9 with #1D set is #DD)\n      moreBlueColour <- lessRedColour + #00001D\n      require moreBlueColour == #CC84FADD\n\n      //Available in different formats as Strings\n      require moreBlueColour.RGB() == $#84FADD\n      require moreBlueColour.RGBA() == $#84FADDCC\n      require moreBlueColour.ARGB() == $#CC84FADD","expectedOutput":"","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_csv.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_csv.html","title":"Parsing CSV","code":"#!ek9\ndefines module site.builtInTypes.csv\n\n  defines program\n\n    CsvExample()\n      stdout <- Stdout()\n\n      result <- CSV().parse(\"name,weight\\nHydrogen,1.008\\nHelium,4.0026\")\n      if result.isOk()\n        table <- result.ok()\n\n        //Read a data row by column name; convert the cell with the target type's constructor\n        helium <- table.getOrDefault(1, CSVRow())\n        weight <- BigDecimal(helium.getOrDefault(\"weight\", \"0\"))\n\n        stdout.println(`Helium weighs ${weight}`)\n      else if result.isError()\n        stdout.println(`Bad CSV: ${result.error()}`)","expectedOutput":"Helium weighs 4.0026\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_date.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_date.html","title":"The Date type","code":"#!ek9\ndefines module site.builtInTypes.date\n\n  defines program\n\n    ShowDateType()\n\n      //3rd of October 2020\n      date1 <- 2020-10-03\n      date2 <- 2020-10-04\n      date3 <- 2020-10-04\n      date4 <- Date()\n      date5 <- Date(2020, 10, 03)\n      date6 <- Date(2020, 10, 04)\n\n      require date1 <> date2\n      require date2 == date3\n\n      require date1 < date2\n      require date1 <= date2\n      require date2 <= date3\n\n      require date2 > date1\n      require date2 >= date1\n      require date3 >= date2\n\n      require ~date4?\n\n      require date1 == date5\n      require date2 == date6\n\n      date4a <- Date().today()\n      require date4a?\n\n      date4.setToday() //Now set to the current date\n\n      //Durations\n      d1 <- P1Y1M4D //one year, one month and four days\n      d2 <- P4W1DT2H59M18S //twenty nine days, two hours, fifty nine minutes and eighteen seconds\n\n      //Note how only the days part of 'd2' is used\n      date4 := date5 + d1\n      require date4 == 2021-11-07\n\n      date4 += d2\n      require date4 == 2021-12-06\n\n      d3 <- date4 - date5\n      require d3 == P1Y2M3D\n\n      //Pipeline with durations and dates.\n      durations as List of Duration := [d1, d2]\n\n      //Because the epoch is 1970-01-01 accumulation starts from that date\n      date7 <- cat durations | collect as Date\n      require date7 == 1971-03-06\n\n      //If you want to accumulate from a specific date you can do this instead\n      date8 <- 0000-01-01\n      cat durations >> date8\n      require date8 == 0001-03-06\n\n      dayOfMonth <- date8.day()\n      monthOfYear <- date8.month()\n      year <- date8.year()\n      dayOfTheWeek <- date8.dayOfWeek()\n\n      require dayOfMonth == 6\n      require monthOfYear == 3\n      require year == 1\n      require dayOfTheWeek == 2","expectedOutput":"","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_date_time.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_date_time.html","title":"The DateTime type","code":"#!ek9\ndefines module site.builtInTypes.dateTime\n\n  defines program\n\n    ShowDateTimeType()\n\n      //3rd of october 2020 @ 12:00 UTC\n      dateTime1 <- 2020-10-03T12:00:00Z\n      dateTime2 <- 2020-10-04T12:15:00-05:00\n      dateTime3 <- 2020-10-04T12:15:00-05:00\n      dateTime4 <- DateTime()\n      dateTime5 <- DateTime(year: 2020, month: 10, dayOfMonth: 3, hour: 12)\n      dateTime6 <- DateTime(year: 2020, month: 10, dayOfMonth: 4, hour: 12, minute: 15)\n\n      require dateTime1 <> dateTime2\n      require dateTime2 == dateTime3\n\n      require dateTime1 < dateTime2\n      require dateTime1 <= dateTime2\n      require dateTime2 <= dateTime3\n\n      require dateTime2 > dateTime1\n      require dateTime2 >= dateTime1\n      require dateTime3 >= dateTime2\n\n      require ~dateTime4?\n\n      require dateTime1 == dateTime5\n\n      dateTime4a <- DateTime().today()\n      require dateTime4a?\n\n      dateTime4.setToday() //Now set to the current dateTime\n\n      //Durations\n      d1 <- P1Y1M4D //one year, one month and 4 days\n      d2 <- P4W1DT2H59M18S //twenty nine days, two hours, fifty nine minutes and eighteen seconds\n\n      dateTime4 := dateTime5 + d1\n      require dateTime4 == 2021-11-07T12:00:00Z\n\n      dateTime4 += d2\n      require dateTime4 == 2021-12-06T14:59:18Z\n\n      d3 <- dateTime4 - dateTime5\n      require d3 == P1Y2M3DT2H59M18S\n\n      d4 <- dateTime2 - dateTime3\n      require d4 == PT0S\n\n      //Think carefully about this (focus on the instant)\n      //At ZULU/GMT/UTC what time will it be in the -05:00 time zone?\n      //2020-10-04T12:15:00-05:00\n      //2020-10-04T12:15:00Z\n      d5 <- dateTime3 - dateTime6\n      require d5 == PT5H\n\n      d6 <- dateTime3.offSetFromUTC()\n      require d6 == PT-5H\n\n      //processing of durations\n      durations as List of Duration := [d1, d2]\n      dateTime7 <- cat durations | collect as DateTime\n      //Because the epoch is 1970-01-01\n      require dateTime7 == 1971-03-06T02:59:18Z\n\n      //From a specific date time add on the durations in turn\n      dateTime8 <- 0000-01-01T00:00:00Z\n      cat durations >> dateTime8\n      require dateTime8 == 0001-03-06T02:59:18Z\n\n      dayOfMonth <- dateTime8.day()\n      monthOfYear <- dateTime8.month()\n      year <- dateTime8.year()\n      dayOfTheWeek <- dateTime8.dayOfWeek()\n      hourOfTheDay <- dateTime8.hour()\n      minuteOfTheHour <- dateTime8.minute()\n      secondOfTheMinute <- dateTime8.second()\n      timeZone <- dateTime8.zone()\n      offset <- dateTime8.offSetFromUTC()\n\n      require dayOfMonth == 6\n      require monthOfYear == 3\n      require year == 1\n      require dayOfTheWeek == 2\n      require hourOfTheDay == 2\n      require minuteOfTheHour == 59\n      require secondOfTheMinute == 18\n      require timeZone == \"Z\"\n      require offset == PT0S","expectedOutput":"","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_digest_hmac.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_digest_hmac.html","title":"Digests and HMACs","code":"#!ek9\ndefines module site.builtInTypes.digestHmac\n\n  defines constant\n\n    sha256HexLength <- 64\n\n  defines program\n\n    DigestAndHmacExample()\n      stdout <- Stdout()\n\n      //Digest is UNKEYED - anyone can compute it, so it proves only integrity\n      fingerprint <- Digest().SHA256(\"the quick brown fox\")\n      stdout.println(`fingerprint length ${length fingerprint}, expected ${sha256HexLength}`)\n\n      //The Bytes overload hashes OCTETS and answers in octets - no encoding assumption\n      //anywhere, so it works on a binary payload as readily as on text\n      payload <- Bytes().withUtf8(\"the quick brown fox\")\n      asOctets <- Digest().SHA256(payload)\n      stdout.println(`same value both ways: ${asOctets.toText(\"hex\") == fingerprint}`)\n\n      //HMAC is KEYED - producing one requires the secret, so it proves WHO\n      key <- Bytes().withUtf8(\"Jefe\")\n      message <- Bytes().withUtf8(\"what do ya want for nothing?\")\n      mac <- HMAC().SHA256(key, message)\n      stdout.println(`mac: ${mac}`)\n\n      //🔑 Change the key and the MAC changes completely. That is the whole difference:\n      //a Digest anyone can forge over new content, an HMAC they cannot without the key.\n      forged <- HMAC().SHA256(Bytes().withUtf8(\"wrong-key\"), message)\n      stdout.println(`a wrong key cannot reproduce it: ${mac <> forged}`)\n\n      //⚠️ VERIFY WITH constantTimeEquals, never with ==. Both answer the same question, but\n      //== is free to stop at the first differing byte, and how long it took then tells an\n      //attacker how many leading bytes they guessed right - a tag forged one byte at a time.\n      stdout.println(`verified: ${mac.constantTimeEquals(HMAC().SHA256(key, message))}`)\n      stdout.println(`forgery rejected: ${mac.constantTimeEquals(forged)}`)\n\n      //Unset in, unset out - never a MAC computed over a substitute value\n      stdout.println(`unset key gives unset mac: ${HMAC().SHA256(Bytes(), message)?}`)","expectedOutput":"fingerprint length 64, expected 64\nsame value both ways: true\nmac: 5BDCC146BF60754E6A042426089575C75A003F089D2739839DEC58B964EC3843\na wrong key cannot reproduce it: true\nverified: true\nforgery rejected: false\nunset key gives unset mac: false\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_dimension.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_dimension.html","title":"The Dimension type","code":"#!ek9\ndefines module site.builtInTypes.dimension\n\n  defines program\n\n    ShowDimensionType()\n\n      dimension1 <- 1cm\n      dimension2 <- 10px\n      dimension3 <- 4.5em\n      dimension4 <- 1.5em\n\n      calc1 <- dimension1 * 2\n      calc2 <- dimension2 / 5\n      calc3 <- dimension3 + 0.6\n      calc4 <- dimension3 + dimension4\n\n      require calc1 == 2cm\n      require calc2 == 2px\n      require calc3 == 5.1em\n      require calc4 == 6em\n\n      //But if we divide a dimension by another dimension we get just a number\n      calc5 <- dimension3 / dimension4\n      require calc5 == 3\n\n      //Normal comparison operators as you would expect\n      require calc3 < calc4\n\n      //But also the coalescing operators\n      lesser <- calc3 <? calc4\n      require lesser == calc3\n\n      calc3 += 0.9\n      require calc3 == calc4\n\n      calc3++\n      require calc3 > calc4\n\n      //Checking the calculation is not actually valid\n      //different types of dimension calc1 is cm and calc2 is px\n      require not (calc1 <> calc2)?\n\n      //This is a test that the comparison was valid, not the result of the comparison\n      require (calc3 < calc4)?\n\n      calc6 <- sqrt calc4\n      require calc6 == 2.449489742783178em\n\n      //Conversion is table-driven: name the target UNIT (1 mile is 1609.344 m by definition)\n      eightMiles <- 8mile\n      inKM <- eightMiles.convert(\"km\")\n      require inKM == 12.874752km\n\n      require #< inKM == 12.874752\n      returnJourney <- -eightMiles\n      require abs returnJourney == eightMiles\n\n      squared <- inKM ^ 2\n      require squared == 165.75923906150402km\n\n      result <- eightMiles + inKM\n      require not result?","expectedOutput":"","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_duration.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_duration.html","title":"Using Duration","code":"#!ek9\ndefines module site.builtintypes.duration\n\n  defines function\n\n    durationExamples()\n      stdout <- Stdout()\n\n      //Some examples of using Duration\n      d1 <- PT1H2M3S //results in 1 hour, 2 minutes and 3 seconds\n      d2 <- P3DT2H59M18S //results in 3 days, 2 hours, 59 minutes and 18 seconds\n      d3 <- P2Y6W3DT8H5M8S //results in 2 years, 45 days, 8 hours, 5 minutes and 8 seconds\n      //Note that 6 weeks was converted to 42 days and then the additional 3 days are added to that\n      d4 <- P2Y2M1W3DT8H5M8S //results in 2 years, 2 months, 10 days, 8 hours, 5 minutes and 8 seconds\n      d5 <- P2W //results in 14 days\n\n      //Mathematics with durations\n      d6 <- PT1H2M1S\n      twice <- d6 * 2 //results in PT2H4M2S i.e. twice the duration in d6\n      scaled <- d6 * 8.25 //results in PT8H31M38S\n      divided <- scaled / 3 //results in PT2H50M32S\n      extended <- d6 + PT20M //results in PT1H22M1S\n      reduced <- d6 - PT2M6S //results in PT59M55S\n      reduced += PT2H5S //results in PT3H\n\n      stdout.println(`${d1} ${d2} ${d3} ${d4} ${d5}`)\n      stdout.println(`${twice} ${scaled} ${divided} ${extended} ${reduced}`)\n\n    durationsOnDates()\n      stdout <- Stdout()\n\n      durations as List of Duration := [P1D, P1M]\n\n      //Adding Durations to a Base Date\n      date <- 2019-06-01\n      //Definition of durations omitted\n      cat durations >> date\n      //The Easiest way to move a date on is by a number of durations\n\n      stdout.println(date)\n\n  defines program\n\n    DurationUse()\n      durationExamples()\n      durationsOnDates()","expectedOutput":"PT1H2M3S P3DT2H59M18S P2Y45DT8H5M8S P2Y2M10DT8H5M8S P14D\nPT2H4M2S PT8H31M38S PT2H50M32S PT1H22M1S PT3H\n2019-07-02\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_integer.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_integer.html","title":"Using Integer and Float","code":"#!ek9\ndefines module site.builtintypes.integer\n\n  defines function\n\n    integerExamples()\n      ->\n        zero as Integer\n        alsoZero as Integer\n        ninety as Integer\n      stdout <- Stdout()\n\n      //Some examples of using Integer\n      i1 <- -9223372036854775808\n      hashCode <- #? i1 //results in -2147483648\n      asFloat <- #^ i1 //promotion to Float results in -9.223372036854776E18\n\n      //Division operations with zero\n      nonResult <- zero / ninety //result is 0 (zero)\n      nonResult := ninety / zero //result is un set i.e not known\n      nonResult := zero / alsoZero //result is un set\n\n      stdout.println(`${hashCode} ${asFloat} ${nonResult?}`)\n\n    integerPipeline()\n      stdout <- Stdout()\n\n      theValues as List of Integer := List() //create a list to capture values in\n\n      //Simple pipeline processing\n      intSum <- for i in 1 ... 11 by 2 | tee in theValues | collect as Integer\n\n      //theValues has the following contents [1, 3, 5, 7, 9, 11]\n      //intSum has the value 36\n\n      stdout.println(`${theValues} ${intSum}`)\n\n    floatExamples()\n      ->\n        zero as Float\n        alsoZero as Float\n        ninety as Float\n      stdout <- Stdout()\n\n      //Some examples of using Float\n      i1 <- -4.9E-324\n      hashCode <- #? i1 //results in -2147483647\n\n      //Division operations with zero\n      nonResult <- zero / ninety //result is 0.0 (zero)\n      nonResult := ninety / zero //result is un set i.e not known\n      nonResult := zero / alsoZero //result is un set\n\n      stdout.println(`${hashCode} ${nonResult?}`)\n\n  defines program\n\n    IntegerUse()\n      integerExamples(0, 0, 90)\n      integerPipeline()\n      floatExamples(0.0, 0.0, 90.0)","expectedOutput":"-2147483648 -9.223372036854776E18 false\n[1, 3, 5, 7, 9, 11] 36\n-2147483647 false\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_interpolation.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_interpolation.html","title":"String interpolation in backtick Strings","code":"#!ek9\ndefines module site.builtInTypes.interpolation\n\n  defines record\n    Person\n      firstName String: String()\n      lastName String: String()\n\n      Person()\n        ->\n          firstName String\n          lastName String\n        require firstName? and lastName?\n\n        this.firstName :=: firstName\n        this.lastName :=: lastName\n\n      operator $ as pure\n        <- rtn String: `${firstName} ${lastName}`\n\n      default operator ?\n\n  defines function\n    getAuthor()\n      <- rtn Person: Person(\"Steve\", \"Limb\")\n\n  defines program\n\n    ShowStringInterpolation()\n      stdout <- Stdout()\n\n      normal <- \"With normal double quote \\\" text\"\n      stdout.println(`[${normal}]`)\n\n      var <- 90.9\n      interpolated <- `A tab\\t ${var} a \" but a back tick \\` the dollar have to be escaped \\$\\nOK?`\n      stdout.println(`[${interpolated}]`)\n\n      me <- Person(\"Steve\", \"Limb\")\n      stdout.println(`Author: ${me} or via function: ${getAuthor()}, direct access \"${me.firstName}\"`)","expectedOutput":"[With normal double quote \" text]\n[A tab\t 90.9 a \" but a back tick ` the dollar have to be escaped $\nOK?]\nAuthor: Steve Limb or via function: Steve Limb, direct access \"Steve\"\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_json_paths.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_json_paths.html","title":"JSON path literals and JSON conversion","code":"#!ek9\ndefines module site.builtInTypes.jsonPaths\n\n  defines program\n\n    ASimpleSetOfPaths()\n      stdout <- Stdout()\n\n      path1 <- $?.some.path.inc[0].array\n      path2 <- $?.another[2][1].multi-dimensional.array.access_value\n\n      simplePath <- $?.aKey\n      firstArrayElement <- $?[0]\n      propertyFromFirstElement <- $?[0].a-field\n      stdout.println(`${path1} ${path2} ${simplePath} ${firstArrayElement} ${propertyFromFirstElement}`)\n\n      //Not to be confused with string conversion\n      anInt <- 90\n      stringRepresentation <- $anInt\n      stdout.println(stringRepresentation)\n\n      //Or json conversion of a record.\n      me <- CustomerDetail(firstName: \"Steve\", lastName: \"Limb\")\n      jsonOfMe <- $$me\n      stdout.println(jsonOfMe)\n\n  defines record\n\n    CustomerDetail\n      firstName as String: String()\n      lastName as String: String()\n\n      CustomerDetail()\n        ->\n          firstName as String\n          lastName as String\n        this.firstName: firstName\n        this.lastName: lastName\n\n      default operator ?\n      default operator $$","expectedOutput":"$?.some.path.inc[0].array $?.another[2][1].multi-dimensional.array.access_value $?.aKey $?[0] $?[0].a-field\n90\n{\"firstName\":\"Steve\",\"lastName\":\"Limb\"}\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_locale.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_locale.html","title":"Locale formatting","code":"#!ek9\ndefines module site.builtInTypes.locale\n\n  defines program\n\n    ShowLocale()\n\n      enGB <- Locale(\"en_GB\")\n      //Note you can use underscore or dash as the separator.\n      enUS <- Locale(\"en-US\")\n      deutsch <- Locale(\"de_DE\")\n      skSK <- Locale(\"sk\", \"SK\")\n\n      i1 <- -92208\n      i2 <- 675807\n\n      presentation <- enGB.format(i1)\n      require presentation == \"-92,208\"\n      presentation := enGB.format(i2)\n      require presentation == \"675,807\"\n\n      presentation := deutsch.format(i1)\n      require presentation == \"-92.208\"\n      presentation := deutsch.format(i2)\n      require presentation == \"675.807\"\n\n      presentation := skSK.format(i1)\n      require presentation == \"-92 208\"\n      presentation := skSK.format(i2)\n      require presentation == \"675 807\"\n\n      f1 <- -4.9E-22\n      f2 <- -1.797693134862395E12\n\n      presentation := enGB.format(f1)\n      require presentation == \"-0.00000000000000000000049\"\n      presentation := enGB.format(f2)\n      require presentation == \"-1,797,693,134,862.395\"\n\n      //With control over number of decimal places displayed\n      presentation := enGB.format(f1, 22)\n      require presentation == \"-0.0000000000000000000005\"\n      presentation := enGB.format(f2, 1)\n      require presentation == \"-1,797,693,134,862.4\"\n\n      presentation := deutsch.format(f1)\n      require presentation == \"-0,00000000000000000000049\"\n      presentation := deutsch.format(f2)\n      require presentation == \"-1.797.693.134.862,395\"\n\n      presentation := skSK.format(f1)\n      require presentation == \"-0,00000000000000000000049\"\n      presentation := skSK.format(f2)\n      require presentation == \"-1 797 693 134 862,395\"\n\n      time1 <- 12:00:01\n\n      presentation := enGB.shortFormat(time1)\n      require presentation == \"12:00\"\n\n      presentation := deutsch.mediumFormat(time1)\n      require presentation == \"12:00:01\"\n\n      date1 <- 2020-10-03\n\n      presentation := enGB.shortFormat(date1)\n      require presentation == \"03/10/2020\"\n\n      presentation := enUS.mediumFormat(date1)\n      require presentation == \"Oct 3, 2020\"\n\n      presentation := skSK.longFormat(date1)\n      require presentation == \"3. októbra 2020\"\n\n      presentation := deutsch.fullFormat(date1)\n      require presentation == \"Samstag, 3. Oktober 2020\"\n\n      dateTime1 <- 2020-10-03T12:00:00Z\n\n      presentation := enUS.shortFormat(dateTime1)\n      require presentation == \"10/3/20, 12:00 PM\"\n\n      presentation := enGB.mediumFormat(dateTime1)\n      require presentation == \"3 Oct 2020, 12:00:00\"\n\n      presentation := deutsch.longFormat(dateTime1)\n      require presentation == \"3. Oktober 2020, 12:00:00 Z\"\n\n      presentation := skSK.fullFormat(dateTime1)\n      require presentation == \"sobota 3. októbra 2020, 12:00:00 Z\"\n\n      thousandsOfChileanCurrency <- 6798.9288#CLF\n      tenPounds <- 10#GBP\n      thirtyDollarsEightyNineCents <- 30.89#USD\n\n      presentation := enGB.format(tenPounds)\n      require presentation == \"£10.00\"\n      presentation := enGB.format(thirtyDollarsEightyNineCents)\n      require presentation == \"US$30.89\"\n      presentation := enGB.format(thousandsOfChileanCurrency)\n      require presentation == \"CLF6,798.9288\"\n\n      presentation := deutsch.format(tenPounds)\n      require presentation == \"10,00 £\"\n      presentation := deutsch.format(thirtyDollarsEightyNineCents)\n      require presentation == \"30,89 $\"\n      presentation := deutsch.format(thousandsOfChileanCurrency)\n      require presentation == \"6.798,9288 CLF\"\n\n      //Without the currency symbol\n      presentation := deutsch.longFormat(tenPounds)\n      require presentation == \"10,00\"\n\n      presentation := deutsch.longFormat(thirtyDollarsEightyNineCents)\n      require presentation == \"30,89\"\n\n      presentation := deutsch.longFormat(thousandsOfChileanCurrency)\n      require presentation == \"6.798,9288\"\n\n      presentation := skSK.format(tenPounds)\n      require presentation == \"10,00 GBP\"\n      presentation := skSK.format(thirtyDollarsEightyNineCents)\n      require presentation == \"30,89 USD\"\n      presentation := skSK.format(thousandsOfChileanCurrency)\n      require presentation == \"6 798,9288 CLF\"\n\n      presentation := enGB.mediumFormat(tenPounds)\n      require presentation == \"£10\"\n      presentation := enGB.mediumFormat(thirtyDollarsEightyNineCents)\n      require presentation == \"US$31\"\n      presentation := enGB.format(money: thousandsOfChileanCurrency, showSymbol: true, showFractionalPart: false)\n      require presentation == \"CLF6,799\"\n\n      presentation := enGB.shortFormat(tenPounds)\n      require presentation == \"10\"\n      presentation := enGB.shortFormat(thirtyDollarsEightyNineCents)\n      require presentation == \"31\"\n      presentation := enGB.format(money: thousandsOfChileanCurrency, showSymbol: false, showFractionalPart: false)\n      require presentation == \"6,799\"","expectedOutput":"","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_maths.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_maths.html","title":"Mathematical functions","code":"#!ek9\ndefines module site.builtInTypes.maths\n\n  defines program\n\n    MathsExample()\n      stdout <- Stdout()\n\n      maths <- Maths()\n\n      //sin of pi/2 is 1.0\n      halfPi <- maths.pi() / 2.0\n      stdout.println(\"sin(pi/2) = \" + $halfPi.sin())","expectedOutput":"sin(pi/2) = 1.0\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_money.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_money.html","title":"The Money type","code":"#!ek9\ndefines module site.builtInTypes.money\n\n  defines program\n\n    ShowMoneyType()\n\n      tenPounds <- 10#GBP\n      require tenPounds == 10.00#GBP\n\n      thirtyDollarsTwentyCents <- 30.2#USD\n      require thirtyDollarsTwentyCents == 30.20#USD\n\n      //Mathematical operators\n      nintyNinePoundsFiftyOnePence <- tenPounds + 89.51#GBP\n      require nintyNinePoundsFiftyOnePence == 99.51#GBP\n\n      require tenPounds < nintyNinePoundsFiftyOnePence\n      require nintyNinePoundsFiftyOnePence > tenPounds\n      require tenPounds <> nintyNinePoundsFiftyOnePence\n      require tenPounds <= 10.00#GBP\n      require tenPounds >= 10.00#GBP\n\n      //As they are different currencies - operation like this are meaningless\n      //You will have to convert to the same currency to compare or combine them.\n      require ~(tenPounds != thirtyDollarsTwentyCents)?\n      require ~(tenPounds == thirtyDollarsTwentyCents)?\n      //The above requirements are checking if the equality test is a valid test, not the result of the equality test.\n\n      //rounding up for money values 49.755 is 49.76\n      fourtyNinePoundsSeventySixPence <- nintyNinePoundsFiftyOnePence/2\n      require fourtyNinePoundsSeventySixPence == 49.76#GBP\n\n      minusFourHundredAndThirtyFivePoundsSixtyPence <- fourtyNinePoundsSeventySixPence * -8.754\n      require minusFourHundredAndThirtyFivePoundsSixtyPence == -435.60#GBP\n\n      nineHundredAndThirtyFivePoundsSixtyPence <- 500#GBP - minusFourHundredAndThirtyFivePoundsSixtyPence\n      require nineHundredAndThirtyFivePoundsSixtyPence == 935.60#GBP\n\n      variableAmount <- (nineHundredAndThirtyFivePoundsSixtyPence * 3) / 18\n      require variableAmount == 155.93#GBP\n\n      multiplier <- nineHundredAndThirtyFivePoundsSixtyPence / variableAmount\n      //A Money / Money ratio is a Float - 6.0001282627 - so bound it, never == it\n      require multiplier > 6.0001 and multiplier < 6.0002\n\n      variableAmount += 4.07#GBP\n      require variableAmount == 160.00#GBP\n\n      variableAmount *= 0.666\n      require variableAmount == 106.56#GBP\n\n      variableAmount -= 0.56#GBP\n      require variableAmount == 106.00#GBP\n\n      variableAmount /= 4\n      require variableAmount == 26.50#GBP\n\n      variableAmount := -variableAmount\n      require variableAmount == -26.50#GBP\n\n      variableAmount := abs variableAmount\n      require variableAmount == 26.50#GBP\n\n      variableAmount := sqrt variableAmount\n      require variableAmount == 5.15#GBP\n\n      variableAmount := variableAmount ^ 6\n      require variableAmount == 18657.07#GBP\n\n      //Division by zero result is not set\n      variableAmount := variableAmount/0\n      require ~variableAmount?\n\n      //Use of two difference currencies together - result is not set\n      variableAmount := tenPounds + thirtyDollarsTwentyCents\n      require ~variableAmount?\n\n      //Example if pipeline to add amounts together\n      amounts as List of Money := [tenPounds, nintyNinePoundsFiftyOnePence, fourtyNinePoundsSeventySixPence]\n      total <- cat amounts | collect as Money\n      require total == 159.27#GBP\n\n      //Provide the exchange rate and convert to USD\n      totalInUSD <- total.convert(1.32845, \"USD\")\n      require totalInUSD == 211.58#USD","expectedOutput":"","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_money_pipeline.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_money_pipeline.html","title":"Adding Money with a pipeline","code":"#!ek9\ndefines module site.builtintypes.moneypipeline\n\n  defines program\n\n    MoneyPipeline()\n      stdout <- Stdout()\n\n      tenPounds <- 10.00#GBP\n      ninetyNinePoundsFiftyOnePence <- 99.51#GBP\n      fortyNinePoundsSeventySixPence <- 49.76#GBP\n\n      total <- cat [tenPounds, ninetyNinePoundsFiftyOnePence, fortyNinePoundsSeventySixPence] | collect as Money\n\n      stdout.println(total)","expectedOutput":"159.27#GBP\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_regex.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_regex.html","title":"Regular expressions and named groups","code":"#!ek9\ndefines module site.builtInTypes.regex\n\n  defines program\n\n    ShowRegExType()\n      stdout <- Stdout()\n\n      sixEx <- /[a-zA-Z0-9]{6}/\n\n      require sixEx matches \"arun32\"\n      require sixEx not matches \"kkvarun32\"\n      require sixEx matches \"JA2Uk2\"\n      require sixEx not matches \"arun$2\"\n\n      regEx <- /[S|s]te(?:ven?|phen)/\n\n      firstCapital <- \"Steve\"\n      firstLower <- \"steve\"\n\n      secondCapital <- \"Stephen\"\n      secondLower <- \"stephen\"\n\n      thirdCapital <- \"Steven\"\n      thirdLower <- \"steven\"\n\n      fourthCapital <- \"Stephene\"\n      fourthLower <- \"stephene\"\n\n      require firstCapital matches regEx and firstLower matches regEx\n      require secondCapital matches regEx and secondLower matches regEx\n      require thirdCapital matches regEx and thirdLower matches regEx\n\n      require fourthCapital not matches regEx\n      require fourthLower not matches regEx\n\n      //String and Regex can work either way around\n      require regEx matches secondCapital\n\n      //Examples using escape of '\\'\n\n      stockExample <- \"This order was placed for QT3000! OK?\"\n      groupEx <- /(.*?)(\\d+)(.*)/\n      require groupEx matches stockExample\n\n      fractionExample <- \"3/4\"\n      fractionEx <- /.*\\/.*/\n      require fractionEx matches fractionExample\n\n      slashEx1 <- /^Some\\\\Thing$/\n      require slashEx1 matches \"Some\\Thing\"\n\n      slashEx2 <- /^Some\\/Thing$/\n      require slashEx2 matches \"Some/Thing\"\n\n      colonDelimited <- \"one:two:three:four:five\"\n      colonRegEx <- /:/\n\n      //You can work with RegEx first or String first\n      whenSplit <- colonDelimited.split(colonRegEx)\n      alsoSplit <- colonRegEx.split(colonDelimited)\n\n      //$ on a List renders the collection with its String elements quoted - it is not a join\n      require length whenSplit == 5\n      require whenSplit.getOrDefault(0, \"?\") == \"one\"\n      require whenSplit.getOrDefault(4, \"?\") == \"five\"\n      require whenSplit == alsoSplit\n\n      //Check on finding groups - the capture groups of the first match, in pattern order\n      extractionCheck <- \"This is a sample Text 1234 with numbers in between.\"\n      extractNumbersEx <- /(.*?)(\\d+)(.*)/\n      matchedGroups <- extractionCheck.group(extractNumbersEx)\n\n      //Three groups: the text before, the digits, the text after\n      require length matchedGroups == 3\n\n      justTheNumber <- cat matchedGroups | skip 1 | head 1 | collect as String\n      //Convert to an Integer - if possible\n      asAnInteger <- Integer(justTheNumber)\n      require $justTheNumber == \"1234\"\n      require asAnInteger == 1234\n\n      //Check just the last two (as an example)\n      lastTwo <- cat matchedGroups | tail 2 | collect as List of String\n      require length lastTwo == 2\n\n      nonExtractionCheck <- \"Another sample but with no numbers in it.\"\n      matchedGroups := nonExtractionCheck.group(extractNumbersEx)\n      //Expecting this to be unset\n      require not matchedGroups?\n\n      //Safe way of accessing some result that might not be set (in this case it is not set)\n      justNotTheNumber <- cat matchedGroups | skip 1 | head 1 | collect as String\n      require not justNotTheNumber?\n\n      //Named groups: ask for one by name - a String, unset when absent\n      namedDate <- /(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})/\n      dueLine <- \"Due 2024-06-15 at noon\"\n      require dueLine.group(namedDate, \"year\") == \"2024\"\n      require not dueLine.group(namedDate, \"hour\")?\n\n      //Replace every match, referring to the groups as $n or ${name} - a name as \\${name} in backticks\n      require dueLine.replace(namedDate, \"$3/$2/$1\") == \"Due 15/06/2024 at noon\"\n      require dueLine.replace(namedDate, `\\${day}.\\${month}.\\${year}`) == \"Due 15.06.2024 at noon\"\n      stdout.println(`Replaced [${dueLine.replace(namedDate, \"<date>\")}]`)","expectedOutput":"Replaced [Due <date> at noon]\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_secure_random.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_secure_random.html","title":"Secure random values","code":"#!ek9\ndefines module site.builtInTypes.secureRandom\n\n  defines function\n\n    //Declaring SecureRandom is the safety property - a SeededRandom will not compile here\n    newSalt() as pure\n      ->\n        generator as SecureRandom\n      <-\n        rtn as Bytes: generator.nextBytes(16)\n\n  defines program\n\n    SecureRandomExample()\n      stdout <- Stdout()\n      generator <- SecureRandom()\n\n      //Exactly the number of octets asked for\n      salt <- newSalt(generator)\n      stdout.println(`salt length: ${length salt}`)\n\n      //A token is octets rendered as text - there is no next() Integer on purpose\n      token <- generator.nextBytes(32).toBase64()\n      stdout.println(`token length: ${length token}`)\n\n      //Two generators never agree - there is no seed for them to share\n      stdout.println(`generators differ: ${SecureRandom().nextBytes(32) <> SecureRandom().nextBytes(32)}`)\n\n      //Zero is EMPTY and SET; an unset or negative count is UNSET\n      stdout.println(`empty is set: ${generator.nextBytes(0)?}`)\n      stdout.println(`negative count: ${generator.nextBytes(-1)?}`)","expectedOutput":"salt length: 16\ntoken length: 44\ngenerators differ: true\nempty is set: true\nnegative count: false\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_string.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_string.html","title":"Working with Strings","code":"#!ek9\ndefines module site.builtInTypes.string\n\n  defines function\n\n    isO() as pure\n      -> c as Character\n      <- o as Integer: c == 'o' or c == 'O' <- 1 else 0\n\n  defines program\n\n    ShowStringType()\n      stdout <- Stdout()\n\n      i1 <- \"The Quick Brown Fox\"\n      i2 <- \"Jumps Over The Lazy Dog\"\n      space <- \" \"\n      i3 <- String()\n      stdout.println(`i3 is set? ${i3?}`)\n\n      hashCode <- #? i1\n      stdout.println(`Hashcode is ${hashCode}`)\n\n      sentence1 <- `${i1} ${i2}`\n      stdout.println(`sentence1 is \"${sentence1}\"`)\n\n      l1 <- length sentence1\n      l2 <- sentence1.length() //the same value, but via the method\n      stdout.println(`Length is ${l1} or ${l2}`)\n\n      oCount <- sentence1.count('o') //only the lower case 'o'\n      eitherCaseOCount <- cat sentence1 | map with isO | collect as Integer //'O' and 'o'\n      stdout.println(`'o' appears ${oCount} times, 'o' or 'O' ${eitherCaseOCount} times`)\n\n      //Alternative way of joining values\n\n      parts <- [i1, space, i2]\n      sentence2 <- cat parts | collect as String\n\n      //OR\n      sentence3 <- cat [i1, space, i2] | collect as String\n      stdout.println(`sentence2 and sentence3 are the same? ${sentence2 == sentence3}`)\n\n      //Mechanism to extract parts of a String\n      jumpingBrownFox <- cat sentence2 | skip 10 | head 15 | collect as String\n      stdout.println(`jumpingBrownFox is \"${jumpingBrownFox}\"`)\n\n      //Note that there is no issue with extending beyond the length of the sentence\n      dog <- cat sentence2 | skip 40 | head 15 | collect as String\n      stdout.println(`dog is \"${dog}\"`)\n\n      //Even this is 'safe' and the result is just not set\n      nonSuch <- cat sentence2 | skip 50 | head 5 | collect as String\n      stdout.println(`nonSuch is set? ${nonSuch?}`)","expectedOutput":"i3 is set? false\nHashcode is -732416445\nsentence1 is \"The Quick Brown Fox Jumps Over The Lazy Dog\"\nLength is 43 or 43\n'o' appears 3 times, 'o' or 'O' 4 times\nsentence2 and sentence3 are the same? true\njumpingBrownFox is \"Brown Fox Jumps\"\ndog is \"Dog\"\nnonSuch is set? false\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_string_literals.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_string_literals.html","title":"Fixed and interpolated String literals","code":"#!ek9\ndefines module site.builtintypes.stringliterals\n\n  defines program\n\n    StringLiterals()\n      stdout <- Stdout()\n\n      //Declare a fixed String literal\n      language <- \"EK9\"\n\n      //Declare a variable to be used in an interpolated String\n      age <- 30\n      //Use the variable in an interpolated String\n      message <- `Your age is ${age}`\n\n      stdout.println(`${language} ${message}`)","expectedOutput":"EK9 Your age is 30\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_time.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_time.html","title":"The Time type","code":"#!ek9\ndefines module site.builtInTypes.time\n\n  defines program\n\n    ShowTimeType()\n\n      //These declarations and operations should be obvious by now if you've read the other sections.\n\n      t1 <- 12:00\n      t2 <- 12:00:01\n      t3 <- 12:00:01\n      t4 <- Time()\n      t5 <- Time(12, 00)\n      t6 <- Time(12, 00, 01)\n\n      require t1 <> t2\n      require t2 == t3\n\n      require t1 < t2\n      require t1 <= t2\n      require t2 <= t3\n\n      require t2 > t1\n      require t2 >= t1\n      require t3 >= t2\n\n      //Check not set\n      require ~t4?\n\n      require t1 == t5\n      require t2 == t6\n\n      //Just create a Time object to get the current time\n      t4a <- SystemClock().time() //t4a will be set to current time\n      t4b <- t4.startOfDay() //t4b will be set to 00:00:00\n      t4c <- t4.endOfDay() //t4c will be set to 23:59:59\n      require t4a?\n      Stdout().println(`Start of day ${t4b}, end of day ${t4c}`)\n\n      //Now actually alter t4 itself\n      t4.set(SystemClock().time()) //t4 will now be set to the current time\n      require t4?\n      t4.setStartOfDay() //Will be set to 00:00:00\n      require t4?\n      t4.setEndOfDay() //Will be set to 23:59:59\n      require t4?\n\n      //Durations\n      d1 <- PT1H2M3S //one hour, two minutes and three seconds\n      d2 <- P3DT2H59M18S //three days, two hours, fifty nine minutes and eighteen seconds\n\n      //Note how only the hours minutes and seconds of 'd2' is used.\n\n      //Addition operations\n      t4 := t5 + d1\n      require t4 == 13:02:03\n      t4 += d2\n      require t4 == 16:01:21\n\n      //Subtraction operations\n      t4 := t5 - d1\n      require t4 == 10:57:57\n      t4 -= d2\n      require t4 == 07:58:39\n\n      //Get the Duration between two times\n      d3 <- 12:04:09 - 06:15:12\n      require d3 == PT5H48M57S\n\n      //Note the different views of a Duration\n      d4 <- 06:15:12 - 12:04:09\n      require d4 == PT-6H11M3S\n      require d4 == PT-5H-48M-57S\n\n      //Example of building a time from a number of durations\n      durations as List of Duration := [d1, d2]\n\n      t7 <- cat durations | collect as Time\n      require t7 == 04:01:21\n\n      //t7 will default to start of the day plus each of the durations piped in\n      //Note that time will just roll over just after 23:59:59\n\n      //It is also possible to get the hour, minute and second from a Time\n      second <- t7.second()\n      minute <- t7.minute()\n      hour <- t7.hour()\n\n      require 4 == hour\n      require 1 == minute\n      require 21 == second","expectedOutput":"Start of day 00:00:00, end of day 23:59:59\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"builtInTypes/builtInTypes_tri_state.ek9","url":"https://ek9.io/examples/builtInTypes/builtInTypes_tri_state.html","title":"Unset values, set checks and guards","code":"#!ek9\ndefines module site.builtInTypes.triState\n\n  defines function\n\n    process()\n      -> name as String\n      Stdout().println(`Processing ${name}`)\n\n    getName()\n      <- rtn as String: \"Steve\"\n\n  defines program\n\n    TriStateExample()\n      //Creating an unset value (NOT null)\n      name <- String()      //Unset String\n      require not name?     //_isSet() returns false\n\n      //Checking if set before use\n      if name?\n        process(name)       //Safe - guaranteed set\n\n      //Guard for safe access\n      if validName <- getName()\n        process(validName)  //Safe - guaranteed set","expectedOutput":"Processing Steve\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"classes/classes_anatomy.ek9","url":"https://ek9.io/examples/classes/classes_anatomy.html","title":"Class anatomy: properties, constructors, methods, override and default operators","code":"#!ek9\ndefines module site.classes.anatomy\n\n  defines class\n\n    //A class is closed unless it says 'as open' - SavingsAccount below extends it.\n    Account as open\n      //Properties are always private; 'as T?' means \"no value until a constructor gives it one\".\n      owner as String?\n      balance as Integer?\n\n      //The properties have no initial value, so a no-argument constructor must be private:\n      //nothing outside the class can make an Account with no owner.\n      default private Account()\n\n      //A constructor's parameters go in one '->' block; 'this.x: x' copies each into its property.\n      Account()\n        ->\n          owner as String\n          balance as Integer\n        this.owner: owner\n        this.balance: balance\n\n      //A method that changes the object.\n      deposit()\n        -> amount as Integer\n        balance += amount\n\n      //A method that returns a value: there is no 'return', the result is the '<-' variable.\n      describe() as pure\n        <- rtn as String: `${owner} holds ${balance}`\n\n      //'?' (set when every property is set), '<=>' (sameness - '==', '<' and the rest are generated\n      //from it), '#?' (goes with sameness) and '$' (the String form).\n      default operator ?\n      default operator <=>\n      default operator #?\n      default operator $\n\n    SavingsAccount extends Account\n      rate as Integer?\n\n      SavingsAccount()\n        ->\n          owner as String\n          balance as Integer\n          rate as Integer\n        super(owner, balance)\n        this.rate: rate\n\n      //'override' is required to replace a method of the super class; 'super.' calls the original.\n      override describe() as pure\n        <- rtn as String: `${super.describe()} at ${rate}%`\n\n      //A sub class with its own properties gives its own '?' and '$'; sameness comes from Account.\n      default operator ?\n      default operator $\n\n  defines program\n\n    ClassAnatomy()\n      stdout <- Stdout()\n\n      ann <- Account(\"Ann\", 120)\n      bob <- SavingsAccount(\"Bob\", 80, 3)\n\n      stdout.println(ann.describe())\n      stdout.println(bob.describe())\n\n      bob.deposit(40)\n      stdout.println(bob.describe())\n\n      stdout.println($ann)\n\n      twin <- Account(\"Ann\", 120)\n      carl <- Account(\"Carl\", 50)\n      stdout.println(`ann == twin: ${ann == twin}`)\n      stdout.println(`ann < carl: ${ann < carl}`)\n      stdout.println(`ann is set: ${ann?}`)","expectedOutput":"Ann holds 120\nBob holds 80 at 3%\nBob holds 120 at 3%\nAccount(owner=Ann, balance=120)\nann == twin: true\nann < carl: true\nann is set: true\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"classes/classes_anatomy_closed_base.ek9","url":"https://ek9.io/examples/classes/classes_anatomy_closed_base.html","title":"Extending a class that is not open","code":"#!ek9\ndefines module bad.site.classes.anatomy.closedbase\n\n  defines class\n\n    Account\n      owner as String?\n\n      default private Account()\n\n      Account()\n        -> owner as String\n        this.owner: owner\n\n      describe() as pure\n        <- rtn as String: `Owned by ${owner}`\n\n      default operator ?\n\n    SavingsAccount extends Account\n\n      SavingsAccount()\n        -> owner as String\n        super(owner)","expectedOutput":null,"kind":"bad","errors":["E05030"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"classes/classes_anatomy_no_isset.ek9","url":"https://ek9.io/examples/classes/classes_anatomy_no_isset.html","title":"A class with properties and no operator ?","code":"#!ek9\ndefines module bad.site.classes.anatomy.noisset\n\n  defines class\n\n    Account\n      owner as String?\n\n      default private Account()\n\n      Account()\n        -> owner as String\n        this.owner: owner\n\n      describe() as pure\n        <- rtn as String: `Owned by ${owner}`","expectedOutput":null,"kind":"bad","errors":["E07235"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"classes/classes_anatomy_public_default.ek9","url":"https://ek9.io/examples/classes/classes_anatomy_public_default.html","title":"Uninitialised properties and no private default constructor","code":"#!ek9\ndefines module bad.site.classes.anatomy.publicdefault\n\n  defines class\n\n    Account\n      owner as String?\n\n      Account()\n        -> owner as String\n        this.owner: owner\n\n      describe() as pure\n        <- rtn as String: `Owned by ${owner}`\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07175"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"classes/classes_anatomy_unset_property.ek9","url":"https://ek9.io/examples/classes/classes_anatomy_unset_property.html","title":"A constructor that leaves a property without a value","code":"#!ek9\ndefines module bad.site.classes.anatomy.unsetproperty\n\n  defines class\n\n    Account\n      owner as String?\n      balance as Integer?\n\n      default private Account()\n\n      Account()\n        -> owner as String\n        this.owner: owner\n\n      describe() as pure\n        <- rtn as String: `${owner} holds ${balance}`\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E08060"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"classes/classes_anatomy_written_equality.ek9","url":"https://ek9.io/examples/classes/classes_anatomy_written_equality.html","title":"Requesting '==' beside '<=>'","code":"#!ek9\ndefines module bad.site.classes.anatomy.writtenequality\n\n  defines class\n\n    Account\n      owner as String?\n\n      default private Account()\n\n      Account()\n        -> owner as String\n        this.owner: owner\n\n      describe() as pure\n        <- rtn as String: `Owned by ${owner}`\n\n      default operator ?\n      default operator <=>\n      default operator ==\n      default operator #?","expectedOutput":null,"kind":"bad","errors":["E07181"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"classes/classes_constructors.ek9","url":"https://ek9.io/examples/classes/classes_constructors.html","title":"Constructors: this(...), super(...), initialisation order and private constructors","code":"#!ek9\ndefines module site.classes.constructors\n\n  defines constant\n    noReading <- 0\n\n  defines class\n\n    Reading as open\n      //A property initialiser runs before ANY constructor body, so 'label' is \"reading\" there.\n      label as String: \"reading\"\n      amount as Integer?\n\n      //A no-argument constructor that delegates with this(...) rather than repeating the work.\n      Reading()\n        this(noReading)\n\n      Reading()\n        -> amount as Integer\n        this.amount: amount\n        label += `: ${amount}`\n\n      //A private constructor is for the class's own use; it delegates first, so every property is set.\n      private Reading()\n        ->\n          label as String\n          amount as Integer\n        this(amount)\n        this.label: `${label}: ${amount}`\n\n      relabelled()\n        -> newLabel as String\n        <- rtn as Reading: Reading(newLabel, amount)\n\n      describe() as pure\n        <- rtn as String: label\n\n      default operator ?\n      default operator $\n\n    Sample extends Reading\n      units as String?\n\n      //Its own property has no initial value, so its default constructor must be private.\n      default private Sample()\n\n      //super(...) runs the Reading constructor (and Reading's initialisers) before this body.\n      Sample()\n        ->\n          amount as Integer\n          units as String\n        super(amount)\n        this.units: units\n\n      override describe() as pure\n        <- rtn as String: `${super.describe()} ${units}`\n\n      default operator ?\n      default operator $\n\n  defines program\n\n    Constructors()\n      stdout <- Stdout()\n\n      stdout.println(Reading().describe())\n      stdout.println(Reading(21).describe())\n      stdout.println(Reading(21).relabelled(\"indoor\").describe())\n      stdout.println(Sample(7, \"mm\").describe())","expectedOutput":"reading: 0\nreading: 21\nindoor: 21\nreading: 7 mm\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"classes/classes_constructors_private_partial.ek9","url":"https://ek9.io/examples/classes/classes_constructors_private_partial.html","title":"Constructing through a private constructor that leaves a property unset","code":"#!ek9\ndefines module bad.site.classes.constructors.privatepartial\n\n  defines class\n\n    Reading\n      label as String?\n      amount as Integer?\n\n      default private Reading()\n\n      Reading()\n        ->\n          label as String\n          amount as Integer\n        this.label: label\n        this.amount: amount\n\n      private Reading()\n        -> label as String\n        this.label: label\n\n      relabelled()\n        -> newLabel as String\n        <- rtn as Reading: Reading(newLabel)\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E08264"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"classes/classes_constructors_private_super.ek9","url":"https://ek9.io/examples/classes/classes_constructors_private_super.html","title":"Relying on a private super constructor","code":"#!ek9\ndefines module bad.site.classes.constructors.privatesuper\n\n  defines class\n\n    Reading as open\n      amount as Integer?\n\n      default private Reading()\n\n      Reading()\n        -> amount as Integer\n        this.amount: amount\n\n      default operator ?\n\n    Sample extends Reading\n      units as String?\n\n      Sample()\n        -> units as String\n        this.units: units\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07176"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"classes/classes_sealed.ek9","url":"https://ek9.io/examples/classes/classes_sealed.html","title":"A sealed class: allow only","code":"#!ek9\ndefines module site.classes.sealed\n\n  defines class\n\n    Shape allow only Circle, Square, Triangle as open\n      area() as pure\n        <- rtn as Float: 0.0\n\n    Circle extends Shape\n      default operator ?\n\n    Square extends Shape\n      default operator ?\n\n    Triangle extends Shape\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"classes/classes_sealed_breach.ek9","url":"https://ek9.io/examples/classes/classes_sealed_breach.html","title":"Extending a sealed class that does not permit it","code":"#!ek9\ndefines module bad.site.classes.sealedbreach\n\n  defines class\n\n    Shape allow only Circle, Square as open\n      area() as pure\n        <- rtn as Float: 0.0\n\n    Circle extends Shape\n      default operator ?\n\n    Square extends Shape\n      default operator ?\n\n    Pentagon extends Shape\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E05240"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"classes/classes_shapes.ek9","url":"https://ek9.io/examples/classes/classes_shapes.html","title":"Shapes, a Coordinate and a function delegate","code":"#!ek9\ndefines module site.classes.shapes\n\n  defines function\n\n    doDrawing() as abstract\n      -> message as String\n\n    doStandardDrawing() is doDrawing\n      -> message as String\n      Stdout().println(message)\n\n    doSimpleDrawing() is doDrawing\n      -> message as String\n      Stdout().println(message.lowerCase())\n\n    doFancyDrawing() extends doDrawing\n      -> message as String\n      Stdout().println(message.upperCase())\n\n    drawShape()\n      -> shape as Shape\n      <- drawn as Bits: Bits(shape.draw())\n\n  defines class\n\n    Coordinate\n      x as Float: 0.0\n      y as Float: 0.0\n\n      //Sort of lombok like, no implementation needed.\n      default Coordinate() as pure\n\n      //Constructor\n      Coordinate() as pure\n        ->\n          initialX as Float\n          initialY as Float\n\n        x :=: initialX\n        y :=: initialY\n\n      x() as pure\n        <- rtn as Float: x\n\n      y() as pure\n        <- rtn as Float: y\n\n      operator + as pure\n        -> coord as Coordinate\n        <- rtn as Coordinate: Coordinate(this.x() + coord.x(), this.y() + coord.y())\n\n      operator +=\n        -> coord as Coordinate\n        this.x += coord.x()\n        this.y += coord.y()\n\n      operator - as pure\n        -> coord as Coordinate\n        <- rtn as Coordinate: Coordinate(this.x() - coord.x(), this.y() - coord.y())\n\n      operator -=\n        -> coord as Coordinate\n        this.x -= coord.x()\n        this.y -= coord.y()\n\n      //Instruction to add in additional operators where these can be auto generated.\n      default operator\n\n    Shape as abstract\n      draw() as abstract\n        <- drawn as Boolean?\n\n    Ellipse extends Shape as open\n      override draw()\n        <- drawn as Boolean: true\n        doDraw(\"Draw Ellipse\")\n\n      protected doDraw()\n        -> message as String\n        Stdout().println(message)\n\n    Circle is Ellipse\n      override draw()\n        <- drawn as Boolean: true\n        doDraw(\"Draw Circle\")\n\n    Rectangle is Shape\n      shouldDraw as Boolean: true\n\n      Rectangle()\n        -> doDraw as Boolean\n        shouldDraw: doDraw\n\n      override draw()\n        <- drawn as Boolean: shouldDraw\n        if shouldDraw\n          Stdout().println(\"Draw Rectangle\")\n\n      default operator ?\n\n    Triangle is Shape\n      override draw()\n        <- drawn as Boolean: true\n        Stdout().println(\"Draw Triangle\")\n\n    Square is Shape\n      drawingFunction as doDrawing?\n      message as String: \"Draw Square\"\n\n      Square()\n        this(doStandardDrawing)\n\n      Square()\n        -> functionToDraw as doDrawing\n        this.drawingFunction = functionToDraw\n\n      override draw()\n        <- drawn as Boolean: true\n        drawingFunction(message)\n\n      default operator ?\n\n  defines program\n    DrawShapes()\n      stdout <- Stdout()\n      stdout.println(\"Will draw shapes\")\n\n      shapes <- [\n        Circle(),\n        Square(),\n        Ellipse(),\n        Rectangle(),\n        Triangle(),\n        Square(doSimpleDrawing),\n        Square(doFancyDrawing),\n        Rectangle(false)\n        ]\n\n      //Procedural\n      for shape in shapes\n        shape.draw()\n\n      //Functional\n      drawnShapes <- cat shapes | map with drawShape | collect as Bits\n      stdout.println(\"Shapes drawn is: \" + $drawnShapes)","expectedOutput":"Will draw shapes\nDraw Circle\nDraw Square\nDraw Ellipse\nDraw Rectangle\nDraw Triangle\ndraw square\nDRAW SQUARE\nDraw Circle\nDraw Square\nDraw Ellipse\nDraw Rectangle\nDraw Triangle\ndraw square\nDRAW SQUARE\nShapes drawn is: 11111110\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"collectionTypes/collectionTypes_dictionary.ek9","url":"https://ek9.io/examples/collectionTypes/collectionTypes_dictionary.html","title":"Dictionaries of values, records and functions","code":"#!ek9\ndefines module site.collectionTypes.dictionary\n\n  defines type\n\n    List of getAddams\n    Dict of (Integer, String)\n    Dict of (String, Date)\n    Dict of (Integer, Addams)\n    Dict of (Integer, getAddams)\n\n  defines record\n\n    Addams\n      name <- String()\n      dob <- Date()\n\n      Addams()\n        -> dateOfBirth as Date\n        if dateOfBirth?\n          dob :=: dateOfBirth\n\n      Addams()\n        ->\n          name as String\n          dateOfBirth as Date\n        this(dateOfBirth)\n        this.name :=: name\n\n      operator $ as pure\n        <- rtn as String: `${name} ${dob}`\n\n      override operator ? as pure\n        <- rtn as Boolean: name? and dob?\n\n      operator #^ as pure\n        <- rtn as String: $this\n\n  defines function\n\n    idToString() as abstract\n      -> id as Integer\n      <- rtn as Optional of String?\n\n    nameToDate() as abstract\n      -> name as String\n      <- rtn as Optional of Date?\n\n    idToAddams() as abstract\n      -> id as Integer\n      <- rtn as Optional of Addams?\n\n    idToGetAddams() as abstract\n      -> id as Integer\n      <- rtn as getAddams?\n\n    addamsToString() as pure\n      -> person as Addams\n      <- rtn as String: `DOB: ${person.dob} Name: ${person.name}`\n\n    getAddams() as abstract\n      <- rtn as Addams?\n\n    getMorticia() is getAddams\n      <- rtn as Addams: Addams(\"Morticia\", 1965-01-03)\n\n    getGomez() is getAddams\n      <- rtn as Addams: Addams( \"Gomez\", 1963-06-08)\n\n    getPugsley() is getAddams\n      <- rtn as Addams: Addams(\"Pugsley\", 1984-10-21)\n\n    getFester() is getAddams\n      <- rtn as Addams: Addams(1960-11-21)\n      rtn.name: \"Fester\"\n\n    getWednesday() is getAddams\n      <- rtn as Addams: Addams()\n      rtn.name: \"Wednesday\"\n      rtn.dob: 1998-01-09\n\n  defines program\n\n    ListDictionaryExample()\n      dictionaryExample <- SimpleDictionaryUse()\n      dictionaryExample.showDictionary()\n\n  defines class\n\n    SimpleDictionaryUse\n      private getName()\n        <- name String: \"Gomez\"\n\n      showDictionary()\n        idNameDictionary <- { 1: getName(), 2: getMorticia().name, 3: \"Pugsley\", 4: \"Fester\", 5: \"Wednesday\" }\n\n        addamsParents <- {\n          getName(): 1963-06-08,\n          getMorticia().name: getMorticia().dob\n          }\n\n        addamsKids <- {\n          \"Pugsley\": 1984-10-21,\n          \"Wednesday\": 1998-01-09\n          }\n\n        nameDateDictionary <- addamsParents + addamsKids + DictEntry(\"Fester\", 1960-11-21)\n\n        idRecordDictionary <- {\n          1: getGomez(),\n          2: getMorticia(),\n          3: getPugsley(),\n          4: getFester(),\n          5: getWednesday()\n          }\n\n        idFunctionDictionary <- {\n          1: getGomez,\n          2: getMorticia,\n          3: getPugsley,\n          4: getFester,\n          5: getWednesday\n          }\n\n        results as List of String: List() of String\n        keyIter <- idNameDictionary.keys()\n        while keyIter?\n          key <- keyIter.next()\n          name <- idNameDictionary.getOrDefault(key, String())\n          if name?\n            results += `Key ${key} with name ${name}`\n\n        //Some keys that won't ever be found\n        invalidValues <- [9, 10, 100]\n\n        keys1 <- idNameDictionary.keys()\n        keys2 <- invalidValues.iterator()\n\n        //This is a dynamic function that 'captures' a variable.\n        nameMapping <- (idNameDictionary) is idToString as function\n          rtn: Optional(idNameDictionary.getOrDefault(id, String()))\n\n        validValues <- cat keys1, keys2 | map with nameMapping | flatten | collect as List of String\n\n        require $validValues == `[\"Gomez\", \"Morticia\", \"Pugsley\", \"Fester\", \"Wednesday\"]`\n\n        //This is also a dynamic function that 'captures' a variable.\n        dateMapping <- (nameDateDictionary) extends nameToDate\n          rtn: Optional(nameDateDictionary.getOrDefault(name, Date()))\n\n        //Now we've used the previous iterator up so need new ones\n        //We can also use the pipeline in column format\n        keys1A <- idNameDictionary.keys()\n        validDates <- cat keys1A\n          | map nameMapping\n          | flatten\n          | map dateMapping\n          | flatten\n          | collect as List of Date\n\n        require $validDates == \"[1963-06-08, 1965-01-03, 1984-10-21, 1960-11-21, 1998-01-09]\"\n\n        //The records and functions held in a Dict are used in the same way.\n        showRecordsAndFunctions(idNameDictionary, idRecordDictionary, idFunctionDictionary)\n\n      private showRecordsAndFunctions()\n        ->\n          idNameDictionary as Dict of (Integer, String)\n          idRecordDictionary as Dict of (Integer, Addams)\n          idFunctionDictionary as Dict of (Integer, getAddams)\n\n        recordMapping <- (idRecordDictionary) extends idToAddams\n          rtn: Optional(idRecordDictionary.getOrDefault(id, Addams()))\n\n        //Now we've used the previous iterator up so need new ones\n        keys1B <- idNameDictionary.keys()\n        validAddams <- cat keys1B\n          | map recordMapping\n          | flatten\n          | collect as List of Addams\n        require length validAddams == 5\n\n        //\"[Gomez 1963-06-08, Morticia 1965-01-03, Pugsley 1984-10-21, Fester 1960-11-21, Wednesday 1998-01-09]\"\n\n        //Example of an inline dynamic function\n        //And and example of cat on a call return.\n        addamsFamily <- cat idNameDictionary.keys()\n          | map with (idFunctionDictionary) extends idToGetAddams (rtn: idFunctionDictionary.getOrDefault(id, getGomez))\n          | call\n          | collect as List of Addams\n        require length addamsFamily == 5\n\n        //\"[Gomez 1963-06-08, Morticia 1965-01-03, Pugsley 1984-10-21, Fester 1960-11-21, Wednesday 1998-01-09]\"\n\n        values <- cat idNameDictionary.values() | collect as List of String\n        require $values == `[\"Gomez\", \"Morticia\", \"Pugsley\", \"Fester\", \"Wednesday\"]`\n\n        found <- idFunctionDictionary.getOrDefault(1, getGomez)\n        require found?\n        require $found() == \"Gomez 1963-06-08\"","expectedOutput":"","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"collectionTypes/collectionTypes_list_creation.ek9","url":"https://ek9.io/examples/collectionTypes/collectionTypes_list_creation.html","title":"Creating Lists and printing them","code":"#!ek9\ndefines module site.collectionTypes.listCreation\n\n  defines function\n\n    toString as pure\n      -> item as Integer\n      <- rtn as String: $item\n\n    isSet as pure\n      -> item as Integer\n      <- rtn as Boolean: item?\n\n  defines program\n\n    ListCreationExample()\n      stdout <- Stdout()\n\n      //A couple of ways to create and empty List of Integer\n      aList as List of Integer: List() of Integer\n      bList <- List() of Integer\n\n      //But if you have a value you want to use from the outset then use this mechanism\n      //The compiler can infer the type is a List of Integer from this.\n      cList <- List(1)\n      stdout.println(`${aList} ${bList} ${cList}`)\n\n      //If you have a full set of integers you know from the outset then you can use\n      //[...] as a short hand for Lists (but they are not arrays and cannot be indexed with []).\n      l1 as List of Integer: [ 57, 55, 26, 24, 21 ]\n\n      //This inferred declaration is preferred and more succinct\n      l2 <- [ 1, 2, 3, 4, 5, 6, 7, Integer() ]\n\n      //List has a $ operator (i.e. convert to string) and so can just print the contents out.\n      stdout.println(\"List l1 is \" + $l1)\n\n      //You can use interpolated Strings if you wish.\n      stdout.println(`List l2 is ${l2}`)\n\n      //Clearly if you had many items, the line length would get very long,\n      //so you can declare lists like this. Also very useful if the items in the list have\n      //complex constructors.\n      l3 <- [\n        1,\n        2,\n        3,\n        4,\n        5,\n        6,\n        7,\n        Integer()\n        ]\n\n      //Again you can just print out like this\n      stdout.println(\"List l3 is \" + $l3)\n\n      //But the alternative is to use streaming pipelines\n      cat l3 | filter by isSet | map with toString > stdout","expectedOutput":"[] [] [1]\nList l1 is [57, 55, 26, 24, 21]\nList l2 is [1, 2, 3, 4, 5, 6, 7, unset]\nList l3 is [1, 2, 3, 4, 5, 6, 7, unset]\n1\n2\n3\n4\n5\n6\n7\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"collectionTypes/collectionTypes_list_of_functions.ek9","url":"https://ek9.io/examples/collectionTypes/collectionTypes_list_of_functions.html","title":"A List of functions, iterated and streamed","code":"#!ek9\ndefines module site.collectionTypes.listOfFunctions\n\n  defines record\n\n    //Designed to hold members of the Addams family only\n    Addams\n      name <- String()\n      dob <- Date()\n\n      //Sample of developer constructors, the no-argument one still gets auto generated.\n      Addams() as pure\n        -> dateOfBirth as Date\n        dob :=? Date(dateOfBirth)\n\n      Addams() as pure\n        ->\n          name as String\n          dateOfBirth as Date\n        this.name :=? String(name)\n        dob :=? Date(dateOfBirth)\n\n      operator $ as pure\n        <- rtn as String: `${name} ${dob}`\n\n      override operator ? as pure\n        <- rtn as Boolean: name? and dob?\n\n      operator #^ as pure\n        <- rtn as String: $this\n\n  defines function\n\n    //Just convert Addams family member to a String representation\n    addamsToString() as pure\n      -> person as Addams\n      <- rtn as String: `DOB: ${person.dob} Name: ${person.name}`\n\n    //Polymorphic abstract function for getting Addams family members\n    getAddams() as pure abstract\n      <- rtn as Addams?\n\n    //Using the full constructor.\n    getMorticia() is getAddams as pure\n      <- rtn as Addams: Addams(\"Morticia\", 1965-01-03)\n\n    //Use developer defined constructor then set the name\n    getGomez() is getAddams as pure\n      <- rtn as Addams: Addams(1963-06-08)\n      rtn.name :=? \"Gomez\"\n\n  //Concept to hold functions that can get Addams family members\n  //Then when the time is right actually call the function to get the member.\n  defines program\n\n    ListFunctionIteratorExample()\n      stdout <- Stdout()\n\n      //Note this is a List of getAddams (function)\n      //EK9 is smart enough to see they both have a common super (function signature)\n      functionList <- [ getGomez, getMorticia ]\n      iter <- functionList.iterator()\n\n      //A bit long winded - see next stream pipeline example\n      while iter?\n        fn <- iter.next()\n        //Now make the call and convert the returned value to a String for output\n        stdout.println($fn())\n        //Because Addams has the promote operator #^ to a String we could just do this\n        stdout.println(fn())\n\n    ListFunctionStreamExample()\n      stdout <- Stdout()\n\n      //Again a list of functions\n      functionList <- [ getGomez, getMorticia ]\n\n      //But here we pipe through to 'call' the function and get the return value\n      //We use the fact that promotion can be used to convert to a default String\n      cat functionList | call > stdout\n\n      //Now if the calls to get members of the Addams family via the function\n      //had to make remote or slow calls, you might be better off calling them concurrently\n      //in an asynchronous manner - note the pipeline will wait until all the calls have completed.\n      //The calls complete in any order, so sort them if the order matters.\n      //But also in this case we want to control to conversion to a String by using a function.\n      cat functionList | async | map with addamsToString | sort > stdout\n\n      //It is also possible to just use this, rather than creating a variable to reference the list\n      cat [ getGomez, getMorticia ] | async | map with addamsToString | sort > stdout\n\n    ListFunctionsInShort()\n      stdout <- Stdout()\n      functionList <- [ getGomez, getMorticia ]\n\n      iter <- functionList.iterator()\n      while iter?\n        fn <- iter.next()\n        stdout.println(fn())\n\n      cat functionList | call | map with addamsToString > stdout\n\n      cat functionList | call > stdout","expectedOutput":{"ListFunctionIteratorExample":"Gomez 1963-06-08\nGomez 1963-06-08\nMorticia 1965-01-03\nMorticia 1965-01-03\n","ListFunctionStreamExample":"Gomez 1963-06-08\nMorticia 1965-01-03\nDOB: 1963-06-08 Name: Gomez\nDOB: 1965-01-03 Name: Morticia\nDOB: 1963-06-08 Name: Gomez\nDOB: 1965-01-03 Name: Morticia\n","ListFunctionsInShort":"Gomez 1963-06-08\nMorticia 1965-01-03\nDOB: 1963-06-08 Name: Gomez\nDOB: 1965-01-03 Name: Morticia\nGomez 1963-06-08\nMorticia 1965-01-03\n"},"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"collectionTypes/collectionTypes_optional.ek9","url":"https://ek9.io/examples/collectionTypes/collectionTypes_optional.html","title":"Optional values, flattened and summed","code":"#!ek9\ndefines module site.collectionTypes.optional\n\n  defines program\n\n    ShowOptionalType()\n      stdout <- Stdout()\n\n      //Example with a fully qualified declaration\n      maybeInteger as Optional of Integer: Optional() of Integer\n\n      //Nothing will be output\n      cat maybeInteger > stdout\n\n      //A type inferred declaration\n      item1 <- Optional(5)\n      cat item1 > stdout\n\n      //two different ways of checking if optional has a value\n      require item1.iterator().hasNext()\n      require item1?\n\n      //read as List of (Optional of Integer)\n      //fully qualified declaration\n      emptyOptionals as List of Optional of Integer: List() of Optional of Integer\n      require emptyOptionals is empty\n\n      //type inference mechanism - much more terse\n      aListOfOptionals <- List(maybeInteger)\n      aListOfOptionals += item1\n      aListOfOptionals += Optional(14)\n\n      //But could have been defined like this\n      someOptionals <- [maybeInteger, item1, Optional(14)]\n      require length someOptionals == 3\n\n      //Use of flatten to get the items out of the optional\n      cat aListOfOptionals | flatten > stdout\n\n      //Calculate the sum of the integers.\n      sum <- cat aListOfOptionals | flatten | collect as Integer\n      require sum == 19\n\n      //Also possible to use an iterator if you wish\n\n      while iter <- item1.iterator() then iter?\n        stdout.println(`Value [${iter.next()}]`)","expectedOutput":"5\n5\n14\nValue [5]\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"collectionTypes/collectionTypes_optional_access.ek9","url":"https://ek9.io/examples/collectionTypes/collectionTypes_optional_access.html","title":"Safe access to an Optional's value","code":"#!ek9\ndefines module site.collectionTypes.optionalAccess\n\n  defines constant\n    sampleName <- \"Steve\"\n\n  defines function\n\n    someAcceptor()\n      -> text as String\n      require text?\n\n    someConsumer() as pure\n      -> text as String\n      require text?\n\n    testSimpleValidIfCheck1()\n      o <- Optional(sampleName)\n\n      //This use of 'is-set' with an 'if' makes the following block safe to call 'get()'\n      if o?\n        name <- o.get()\n        require name?\n\n    testUsingConsumer() as pure\n      o <- Optional(sampleName)\n\n      //Within a pure context a 'Consumer of T' is inferred for the function 'someConsumer'\n      o.whenPresent(someConsumer)\n\n    testUsingAcceptor()\n      o <- Optional(sampleName)\n\n      //Within a none-pure context an 'Acceptor of T' is inferred for the function 'someAcceptor'\n      o.whenPresent(someAcceptor)\n\n    testUsingTernary() as pure\n      o <- Optional(sampleName)\n\n      //This use of 'is-set' with a ternary control makes the following block safe to call 'get()'\n      name <- o? <- o.get() else String()\n      require name?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"collectionTypes/collectionTypes_priority_queue.ek9","url":"https://ek9.io/examples/collectionTypes/collectionTypes_priority_queue.html","title":"A PriorityQueue ordered by a comparator, bounded with withSize","code":"#!ek9\ndefines module site.collectionTypes.priorityQueue\n\n  defines function\n\n    suitableLength() as pure\n      -> text as String\n      <- rtn as Boolean?\n      minimumLength <- 5\n      rtn: length of text > minimumLength\n\n    stringCompare() as pure\n      ->\n        t1 as String\n        t2 as String\n      <-\n        r as Integer: t1 <=> t2\n\n  defines program\n\n    ShowPriorityQueue()\n      stdout <- Stdout()\n\n      qOne <- PriorityQueue(\"Bill\").withComparator(stringCompare)\n\n      qOne += \"And\"\n      qOne += \"Ted\"\n      qOne += \"Excellent\"\n      qOne += \"Adventure\"\n      qOne += \"Outrageous\"\n      qOne += \"Bogus\"\n\n      //They come out in order by String comparison, not in the order added.\n      allEntries <- cat qOne | collect as List of String\n      stdout.println(`All entries: ${allEntries}`)\n\n      //Now make a queue that is finite, with just 3 entries\n      topThree <- qOne.withSize(3)\n\n      //Access to a list can be done just like this\n      stdout.println(`Top three: ${topThree.list()}`)\n\n      //Missy will make the cut!\n      topThree += \"Missy\"\n      stdout.println(`After adding Missy: ${topThree.list()}`)\n\n      //Use PriorityQueue to collect up and keep ordered as part of pipeline\n      bestTwo <- PriorityQueue() of String\n      bestTwo := bestTwo.withSize(2).withComparator(stringCompare)\n\n      //Note this uses allEntries again, but filter before queueing\n      cat allEntries | filter by suitableLength > bestTwo\n      stdout.println(`Best two longer than five characters: ${bestTwo.list()}`)","expectedOutput":"All entries: [\"Ted\", \"Outrageous\", \"Excellent\", \"Bogus\", \"Bill\", \"And\", \"Adventure\"]\nTop three: [\"Ted\", \"Outrageous\", \"Excellent\"]\nAfter adding Missy: [\"Ted\", \"Outrageous\", \"Missy\"]\nBest two longer than five characters: [\"Outrageous\", \"Excellent\"]\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"collectionTypes/collectionTypes_result.ek9","url":"https://ek9.io/examples/collectionTypes/collectionTypes_result.html","title":"Safe access to a Result's OK and error values","code":"#!ek9\ndefines module site.collectionTypes.result\n\n  defines constant\n    sampleName <- \"Steve\"\n\n  defines function\n\n    getResult1() as pure\n      -> text as String\n      <- rtn as Result of (String, Integer): Result(text, Integer())\n\n    //Note that due to the function signatures the appropriate Consumer/Acceptor super function is inferred\n    someAcceptor()\n      -> text as String\n      require text?\n\n    someConsumer() as pure\n      -> text as String\n      require text?\n\n    someErrorAcceptor()\n      -> code as Integer\n      require code?\n\n    someErrorConsumer() as pure\n      -> code as Integer\n      require code?\n\n    testValidUseDueToChecks1()\n      r <- Result(sampleName, Integer())\n      //So this should be valid as a check has been done\n      if r?\n        okValue <- r.ok()\n        require okValue?\n\n    testValidUseDueToChecks2()\n      r <- Result(sampleName, Integer())\n      //So this should be valid as a check has been done this time isOk()\n      if r.isOk()\n        okValue <- r.ok()\n        require okValue?\n\n    testValidUseDueToChecks3()\n      r <- Result(sampleName, Integer())\n      //So this should be valid as a check has been done this time isOk() via a ternary\n      okValue <- r.isOk() <- r.ok() else String()\n      require okValue?\n\n      //You can also do this\n      errorValue <- r.isError() <- r.error() else Integer()\n      require not errorValue?\n\n    testValidUseDueToChecks4()\n      r <- Result(sampleName, Integer())\n      someBoolean <- true\n\n      okValue <- someBoolean and r? <- r.ok() else String()\n      require okValue?\n\n    testAccessResult()\n      r <- getResult1(sampleName)\n\n      //These methods can be called with specific acceptors/consumers and those will only be called if the\n      //result has an 'OK' value.\n      r.whenOk(someAcceptor)\n      r.whenOk(someConsumer)\n\n      //Likewise for errors.\n      r.whenError(someErrorAcceptor)\n      r.whenError(someErrorConsumer)\n\n      //Now you can also check if the result is in error or ok like this\n      require r.isOk() or r.isError()\n\n      //Now if you are expecting a specific OK value - you can do this.\n      hasOkSteve <- r contains sampleName\n      require hasOkSteve\n\n      maybeTheOkValue <- String()\n      //You can also do this quite safely - because if there is no OK value - the iterator will unset\n      //So the loop won't be processed\n      while iter <- r.iterator() then iter.hasNext()\n        maybeTheOkValue :=: iter.next()\n\n      //So if it was set then you'd have the value (or a copy of it in this case)\n      require maybeTheOkValue?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"collectionTypes/collectionTypes_set.ek9","url":"https://ek9.io/examples/collectionTypes/collectionTypes_set.html","title":"A Set keeps one of each value","code":"#!ek9\ndefines module site.collectionTypes.set\n\n  defines program\n\n    SetCreationExample()\n      stdout <- Stdout()\n\n      //An empty Set of String, then a Set created with a value\n      names as Set of String: Set()\n      seen <- Set(\"Alpha\")\n\n      //Adding a duplicate has no effect; iteration keeps first-insertion order\n      names += \"Zeta\"\n      names += \"Alpha\"\n      names += \"Zeta\"\n\n      //Membership test and unique count\n      stdout.println(\"Contains Zeta? \" + $names.contains(\"Zeta\"))\n      stdout.println(\"Unique count: \" + $length names)\n      stdout.println(\"Set names is \" + $names)\n      stdout.println(\"Set seen is \" + $seen)","expectedOutput":"Contains Zeta? true\nUnique count: 2\nSet names is {\"Zeta\", \"Alpha\"}\nSet seen is {\"Alpha\"}\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"commandline/broken/commandline_broken.ek9","url":"https://ek9.io/examples/commandline/broken/commandline_broken.html","title":"A program that does not compile","code":"#!ek9\ndefines module bad.site.commandline.broken\n\n  defines function\n\n    nextCount()\n      -> count as Integer\n      <- result as Integer: coutn + 1","expectedOutput":null,"kind":"bad","errors":["E50001"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"commandline/errorformat/commandline_errorformat.ek9","url":"https://ek9.io/examples/commandline/errorformat/commandline_errorformat.html","title":"A typo the compiler reports at each verbosity level","code":"#!ek9\ndefines module bad.site.commandline.errorformat\n\n  defines function\n\n    nextCount()\n      -> count as Integer\n      <- result as Integer: coutn + 1","expectedOutput":null,"kind":"bad","errors":["E50001"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"commandline/passthrough/commandline_passthrough.ek9","url":"https://ek9.io/examples/commandline/passthrough/commandline_passthrough.html","title":"A program that reads stdin and writes stdout","code":"#!ek9\ndefines module site.commandline.passthrough\n\n  defines program\n\n    PassThrough()\n      stdin <- Stdin()\n      stdout <- Stdout()\n\n      inputLine <- stdin.next()\n      stdout.println(inputLine)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"commonDesignPatterns/commonDesignPatterns_client.ek9","url":"https://ek9.io/examples/commonDesignPatterns/commonDesignPatterns_client.html","title":"Client code configuring the library service in several ways","code":"#!ek9\ndefines module site.commonDesignPatterns.client\n\n  references\n    site.commonDesignPatterns.library::applyConfigurations\n    site.commonDesignPatterns.library::conditionallyApplyConfiguration\n    site.commonDesignPatterns.library::ConfigurationDetails\n    site.commonDesignPatterns.library::SomeConfigurableService\n\n  defines function\n\n    testAPlainConfiguration() as pure\n\n      someServer <- SomeConfigurableService()\n      someServer.underTakeServiceOperations()\n\n      asConfigured <- someServer.configurationDetails()\n      require asConfigured?\n\n    withSpecificValues() as pure\n      -> details as ConfigurationDetails\n      details.name :=? \"Specific Value\"\n      details.useMapping :=? false\n      details.frequencyOfChecks :=? 21\n\n    testABespokePureConfiguration1() as pure\n\n      someServer <- SomeConfigurableService(conditionallyApplyConfiguration(withSpecificValues))\n      someServer.underTakeServiceOperations()\n\n      asConfigured <- someServer.configurationDetails()\n      require asConfigured?\n\n  defines function\n\n    withSpecificName()\n      -> details as ConfigurationDetails\n      details.name: \"specific\"\n\n    enableMapping()\n      -> details as ConfigurationDetails\n      details.useMapping: true\n\n    testAFlexibleBespokeConfiguration()\n\n      someServer <- SomeConfigurableService(\n        applyConfigurations(\n          [ withSpecificName, enableMapping ]\n          )\n        )\n\n      someServer.underTakeServiceOperations()\n\n      asConfigured <- someServer.configurationDetails()\n      require asConfigured?\n\n    testACopyAndInitialisePureConfiguration() as pure\n\n      specifics <- () is Consumer of ConfigurationDetails as pure function\n        t.name :=? \"Retained Value\"\n        t.useMapping :=? false\n\n      configuration <- ConfigurationDetails()\n      configuration.name :=? \"Ignored Value\"\n      configuration.frequencyOfChecks :=? 16\n\n      someServer <- SomeConfigurableService(ConfigurationDetails(specifics, configuration))\n\n      someServer.underTakeServiceOperations()\n\n      asConfigured <- someServer.configurationDetails()\n\n      //asConfigured would be 'name = \"Retained Value\", useMapping = false, frequencyOfChecks = 16'\n      require asConfigured?\n\n  defines program\n\n    ConfigureTheService()\n      testAPlainConfiguration()\n      testABespokePureConfiguration1()\n      testAFlexibleBespokeConfiguration()\n      testACopyAndInitialisePureConfiguration()","expectedOutput":"Processing Service operation for default\nProcessing Service frequency 6\nProcessing Service operation for Specific Value\nProcessing Service frequency 21\nProcessing Service operation for specific\nWill use mapping\nProcessing Service frequency 6\nProcessing Service operation for Retained Value\nProcessing Service frequency 16\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"commonDesignPatterns/commonDesignPatterns_library.ek9","url":"https://ek9.io/examples/commonDesignPatterns/commonDesignPatterns_library.html","title":"A configurable library service: a record built by functions","code":"#!ek9\ndefines module site.commonDesignPatterns.library\n\n  defines record\n\n    ConfigurationDetails\n      name <- String()\n      useMapping <- Boolean()\n      frequencyOfChecks <- Integer()\n\n      default ConfigurationDetails() as pure\n\n      ConfigurationDetails() as pure\n        -> initializer as Consumer of ConfigurationDetails\n        initializer(this)\n\n      ConfigurationDetails() as pure\n        -> copyFrom as ConfigurationDetails\n        this :=: copyFrom\n\n      ConfigurationDetails() as pure\n        ->\n          initializer as Consumer of ConfigurationDetails\n          copyFrom as ConfigurationDetails\n\n        initializer(this)\n        this :=: copyFrom\n\n      operator :=:\n        -> copyFrom as ConfigurationDetails\n\n        name :=? String(copyFrom.name)\n        useMapping :=? Boolean(copyFrom.useMapping)\n        frequencyOfChecks :=? Integer(copyFrom.frequencyOfChecks)\n\n      default operator ?\n      default operator $\n\n  defines class\n\n    SomeConfigurableService\n\n      configuration as ConfigurationDetails: ConfigurationDetails()\n\n      //With no configuration given, the library's defaults are used.\n      SomeConfigurableService() as pure\n        configuration :=? ConfigurationDetails(defaultConfiguration)\n\n      SomeConfigurableService() as pure\n        -> useConfiguration as ConfigurationDetails\n        configuration :=? ConfigurationDetails(useConfiguration)\n\n      underTakeServiceOperations() as pure\n        stdout <- Stdout()\n        if configuration.name?\n          stdout.println(`Processing Service operation for ${configuration.name}`)\n        if configuration.useMapping\n          stdout.println(`Will use mapping`)\n        if configuration.frequencyOfChecks?\n          stdout.println(`Processing Service frequency ${configuration.frequencyOfChecks}`)\n\n      configurationDetails() as pure\n        <- rtn as String: $configuration\n\n      default operator ?\n\n  defines function\n\n    //The fallback: sets only what nothing else has set. Each builder below applies it last.\n    defaultConfiguration() as pure\n      -> details as ConfigurationDetails\n      details.name :=? \"default\"\n      details.useMapping :=? false\n      details.frequencyOfChecks :=? 6\n\n    applyConfigurations()\n      -> changes as List of Acceptor of ConfigurationDetails\n      <- configuration as ConfigurationDetails: ConfigurationDetails()\n      for change in changes\n        change(configuration)\n      defaultConfiguration(configuration)\n\n    applyConfiguration()\n      -> change as Acceptor of ConfigurationDetails\n      <- configuration as ConfigurationDetails: ConfigurationDetails()\n      change(configuration)\n      defaultConfiguration(configuration)\n\n    conditionallyApplyConfigurations() as pure\n      -> changes as List of Consumer of ConfigurationDetails\n      <- configuration as ConfigurationDetails: ConfigurationDetails()\n      for change in changes\n        change(configuration)\n      defaultConfiguration(configuration)\n\n    conditionallyApplyConfiguration() as pure\n      -> change as Consumer of ConfigurationDetails\n      <- configuration as ConfigurationDetails: ConfigurationDetails()\n      change(configuration)\n      defaultConfiguration(configuration)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"components/components_hrsystem.ek9","url":"https://ek9.io/examples/components/components_hrsystem.html","title":"An HR system wired from components","code":"#!ek9\ndefines module site.components.hrsystem\n\n  defines type\n\n    EmployeeId as Integer constrain\n      > 0\n\n    Name as String constrain as\n      matches /^[a-zA-Z -]+$/\n\n    RoleName\n      manager\n      secretary\n      sales\n      factory\n\n  defines record\n\n    Address\n      street <- String()\n      street2 <- String()\n      city <- String()\n      state <- String()\n      zipcode <- String()\n\n      default Address()\n\n      Address()\n        ->\n          street as String\n          street2 as String\n          city as String\n          state as String\n          zipcode as String\n        this.street: street\n        this.street2: street2\n        this.city: city\n        this.state: state\n        this.zipcode: zipcode\n\n      override operator ? as pure\n        <- rtn as Boolean: street? and city? and state? and zipcode?\n\n      operator $ as pure\n        <- rtn as String: street2? <- `${street}\\n${street2}\\n${city} ${state} ${zipcode}` else `${street}\\n${city} ${state} ${zipcode}`\n\n  defines trait\n\n    Role\n      performDuties()\n        -> hours as Integer\n        <- activity as String?\n\n      override operator ? as pure\n        <- rtn as Boolean: true\n\n    PayrollCalculator\n      resetHoursWorked()\n\n      trackWork()\n        -> hours as Integer\n\n      calculatePayroll()\n        <- amount as Money?\n\n      override operator ? as pure\n        <- rtn as Boolean: true\n\n    RoleDB\n      findRole()\n        -> roleName as RoleName\n        <- rtn as Role?\n\n    AddressDB\n      findEmployeeAddress()\n        -> employeeId as EmployeeId\n        <- rtn as Address?\n\n      addEmployeeAddress()\n        ->\n          employeeId as EmployeeId\n          address as Address\n\n    PayrollPolicyDB\n      findPayrollPolicy()\n        -> employeeId as EmployeeId\n        <- rtn as PayrollPolicy?\n\n      addPayrollPolicy()\n        ->\n          employeeId as EmployeeId\n          payrollPolicy as PayrollPolicy\n\n    EmployeeDB\n      employed()\n        <- employedStaff as List of Employment?\n\n      changeRole()\n        ->\n          employeeId as EmployeeId\n          newRole as RoleName\n\n      addEmployee()\n        ->\n          person as Person\n          role as RoleName\n          payrollPolicy as PayrollPolicy\n\n  defines class\n\n    PayrollPolicy with trait of PayrollCalculator as abstract\n      hoursWorked <- 0\n\n      override resetHoursWorked()\n        hoursWorked = 0\n\n      override trackWork()\n        -> hours as Integer\n        hoursWorked += hours\n\n      hoursWorked()\n        <- hours as Integer: hoursWorked\n\n      override operator ? as pure\n        <- rtn as Boolean: hoursWorked?\n\n    HourlyPolicy extends PayrollPolicy\n      hourRate <- Money()\n\n      HourlyPolicy()\n        -> hourRate as Money\n        this.hourRate = hourRate\n\n      override calculatePayroll()\n        <- amount as Money: hourRate * hoursWorked()\n\n      default operator ?\n\n    SalaryPolicy extends PayrollPolicy as open\n      weeklySalary <- Money()\n\n      SalaryPolicy()\n        -> weeklySalary as Money\n        this.weeklySalary = weeklySalary\n\n      override calculatePayroll()\n        <- amount as Money: weeklySalary\n\n      default operator ?\n\n    CommissionPolicy extends SalaryPolicy\n      commissionPerSale <- Money()\n\n      CommissionPolicy()\n        ->\n          weeklySalary as Money\n          commissionPerSale as Money\n        super(weeklySalary)\n        this.commissionPerSale = commissionPerSale\n\n      override calculatePayroll()\n        <- amount as Money: super.calculatePayroll() + commission()\n\n      private commission()\n        <- amount as Money: commissionPerSale/5.0 * hoursWorked()\n\n      default operator ?\n\n    ManagerRole with trait of Role\n      override performDuties()\n        -> hours as Integer\n        <- activity as String: `screams and yells for ${hours} hours.`\n\n    SecretaryRole with trait of Role\n      override performDuties()\n        -> hours as Integer\n        <- activity as String: `does paperwork for ${hours} hours.`\n\n    SalesRole with trait of Role\n      override performDuties()\n        -> hours as Integer\n        <- activity as String: `expends ${hours} hours on the phone.`\n\n    FactoryRole with trait of Role\n      override performDuties()\n        -> hours as Integer\n        <- activity as String: `manufactures gadgets for ${hours} hours.`\n\n    GeneralRole with trait of Role\n      override performDuties()\n        -> hours as Integer\n        <- activity as String: `general activities for ${hours} hours.`\n\n    Person\n      name <- Name()\n      address <- Address()\n\n      Person()\n        ->\n          name as Name\n          address as Address\n        this.name: name\n        this.address: address\n\n      name()\n        <- rtn as Name: name\n\n      address()\n        <- rtn as Address: address\n\n      override operator ? as pure\n        <- rtn as Boolean: name? and address?\n\n      operator $ as pure\n        <- rtn as String: $name\n\n    Employee\n      id <- EmployeeId()\n      person <- Person()\n\n      Employee()\n        ->\n          id as EmployeeId\n          person as Person\n        require id? and person?\n        this.id: id\n        this.person: person\n\n      id()\n        <- rtn as EmployeeId: id\n\n      person()\n        <- rtn as Person: person\n\n      override operator ? as pure\n        <- rtn as Boolean: id? and person?\n\n      operator $ as pure\n        <- rtn as String: `${id} - ${person}`\n\n    Employment with trait of Role by role, PayrollCalculator by payroll\n      employee <- Employee()\n      role as Role: GeneralRole()\n      payroll as PayrollCalculator: HourlyPolicy(Money())\n\n      Employment()\n        ->\n          employee as Employee\n          role as Role\n          payroll as PayrollCalculator\n        require employee? and role? and payroll?\n        this.employee: employee\n        this.role: role\n        this.payroll: payroll\n\n      changeRole()\n        -> newRole as Role\n        role: newRole\n\n      work()\n        -> amountWorked as Duration\n        <- dutiesPerformed as String?\n        //Note that duration is converted to hours from this point on.\n        require amountWorked.hours() >= 0\n\n        dutiesPerformed: performDuties(amountWorked.hours())\n        payroll.trackWork(amountWorked.hours())\n\n      employeeAddress()\n        <- rtn as Address: employee.person().address()\n\n      employee()\n        <- rtn as Employee: employee\n\n      override operator ? as pure\n        <- rtn as Boolean: role? and payroll?\n\n      operator $ as pure\n        <- rtn as String: $employee\n\n    InMemoryRoleDB with trait of RoleDB\n      roles as Dict of (RoleName, Role): {\n        RoleName.manager: ManagerRole(),\n        RoleName.secretary: SecretaryRole(),\n        RoleName.sales: SalesRole(),\n        RoleName.factory: FactoryRole()\n        }\n\n      override findRole()\n        -> roleName as RoleName\n        <- rtn as Role?\n        rtn: roles.getOrDefault(roleName, ManagerRole())\n\n      default operator ?\n\n    InMemoryAddressDB with trait of AddressDB\n      employeeAddresses as Dict of (EmployeeId, Address): {\n        EmployeeId(1): Address(street: \"121 Admin Rd.\", street2: String(), city: \"Concord\", state: \"NH\", zipcode: \"03301\"),\n        EmployeeId(2): Address(street: \"67 Paperwork Ave\", street2: String(), city: \"Manchester\", state: \"NH\", zipcode: \"03101\"),\n        EmployeeId(3): Address(street: \"15 Rose St\", street2: \"Apt. B-1\", city: \"Concord\", state: \"NH\", zipcode: \"03301\"),\n        EmployeeId(4): Address(street: \"39 Sole St.\", street2: String(), city: \"Concord\", state: \"NH\", zipcode: \"03301\"),\n        EmployeeId(5): Address(street: \"99 Mountain Rd.\", street2: String(), city: \"Concord\", state: \"NH\", zipcode: \"03301\")\n        }\n\n      override findEmployeeAddress()\n        -> employeeId as EmployeeId\n        <- rtn as Address: Address()\n        rtn: employeeAddresses.getOrDefault(employeeId, Address())\n\n      override addEmployeeAddress()\n        ->\n          employeeId as EmployeeId\n          address as Address\n        employeeAddresses += DictEntry(employeeId, address)\n\n      default operator ?\n\n    InMemoryPayrollPolicyDB with trait of PayrollPolicyDB\n      employeePayrollPolicies as Dict of (EmployeeId, PayrollPolicy): {\n        EmployeeId(1): SalaryPolicy(3000#USD),\n        EmployeeId(2): SalaryPolicy(1500#USD),\n        EmployeeId(3): CommissionPolicy(1000#USD, 100#USD),\n        EmployeeId(4): HourlyPolicy(15#USD),\n        EmployeeId(5): HourlyPolicy(9#USD)\n        }\n\n      override findPayrollPolicy()\n        -> employeeId as EmployeeId\n        <- rtn as PayrollPolicy?\n        rtn: employeePayrollPolicies.getOrDefault(employeeId, HourlyPolicy(9#USD))\n\n      override addPayrollPolicy()\n        ->\n          employeeId as EmployeeId\n          payrollPolicy as PayrollPolicy\n        employeePayrollPolicies += DictEntry(employeeId, payrollPolicy)\n\n      default operator ?\n\n    InMemoryEmployeeDB with trait of EmployeeDB, RoleDB by roleDB, AddressDB by addressDB, PayrollPolicyDB by payrollPolicyDB\n      roleDB as RoleDB?\n      addressDB as AddressDB?\n      payrollPolicyDB as PayrollPolicyDB?\n\n      employedStaff as Dict of (EmployeeId, Employment): Dict()\n      nextEmployeeId as EmployeeId: EmployeeId(6)\n\n      default private InMemoryEmployeeDB()\n\n      InMemoryEmployeeDB()\n        ->\n          roleDB as RoleDB\n          addressDB as AddressDB\n          payrollPolicyDB as PayrollPolicyDB\n        this.roleDB: roleDB\n        this.addressDB: addressDB\n        this.payrollPolicyDB: payrollPolicyDB\n        populateEmployedStaff()\n\n      private populateEmployedStaff()\n        createEmployment(EmployeeId(1), Name(\"Mary Poppins\"), RoleName.manager)\n        createEmployment(EmployeeId(2), Name(\"John Smith\"), RoleName.secretary)\n        createEmployment(EmployeeId(3), Name(\"Kevin Bacon\"), RoleName.sales)\n        createEmployment(EmployeeId(4), Name(\"Jane Doe\"), RoleName.factory)\n        createEmployment(EmployeeId(5), Name(\"Robin Williams\"), RoleName.secretary)\n\n      override employed()\n        <- staff as List of Employment: List()\n        values <- this.employedStaff.values()\n        cat values > staff\n\n      override changeRole()\n        ->\n          employeeId as EmployeeId\n          newRole as RoleName\n        if employedStaff contains employeeId\n          employment <- employedStaff.getOrDefault(employeeId, Employment())\n          employment.changeRole(findRole(newRole))\n\n      override addEmployee()\n        ->\n          person as Person\n          role as RoleName\n          payrollPolicy as PayrollPolicy\n        newEmployeeId <- nextEmployeeId()\n\n        addEmployeeAddress(newEmployeeId, person.address())\n        addPayrollPolicy(newEmployeeId, payrollPolicy)\n\n        employment <- Employment(Employee(newEmployeeId, person), findRole(role), payrollPolicy)\n        addEmployment(employment)\n\n      private nextEmployeeId()\n        <- id as EmployeeId: EmployeeId()\n        id :=: nextEmployeeId\n        nextEmployeeId++\n\n      private createEmployment()\n        ->\n          id as EmployeeId\n          name as Name\n          theRole as RoleName\n        address <- findEmployeeAddress(id)\n        employeeRole <- findRole(theRole)\n        payrollPolicy <- findPayrollPolicy(id)\n        addEmployment(Employment(Employee(id, Person(name, address)), employeeRole, payrollPolicy))\n\n      private addEmployment()\n        -> employment as Employment\n        employedStaff += DictEntry(employment.employee().id(), employment)\n\n      default operator ?\n\n    ProductivitySystem with trait of StringOutput by output\n      output as StringOutput?\n\n      default private ProductivitySystem()\n\n      ProductivitySystem()\n        -> output as StringOutput\n        this.output: output\n\n      track()\n        ->\n          employed as List of Employment\n          amountWorked as Duration\n        println(\"Tracking Employee Productivity\")\n        println(\"==============================\")\n        for employment in employed\n          dutiesPerformed <- employment.work(amountWorked)\n          println(`Employee ${employment}: `)\n          println(\" - \" + dutiesPerformed)\n          println(\"\")\n        println(\"\")\n\n      default operator ?\n\n    PayrollSystem with trait of StringOutput by output\n      output as StringOutput?\n\n      default private PayrollSystem()\n\n      PayrollSystem()\n        -> output as StringOutput\n        this.output: output\n\n      calculatePayroll()\n        -> employed as List of Employment\n        println(\"Calculating Payroll\")\n        println(\"===================\")\n        for employment in employed\n          println(\"Payroll for: \" + $employment)\n          println(\"- Check amount: \" + $employment.calculatePayroll())\n          if employment.employeeAddress()?\n              println(\"- Sent to:\")\n              println($employment.employeeAddress())\n          println(\"\")\n\n      default operator ?\n\n  defines component\n\n    OutputInterface as abstract\n      output()\n        <- outputTo as StringOutput: Stdout()\n\n    StdoutInterface is OutputInterface\n\n    StderrInterface is OutputInterface\n      override output()\n        <- outputTo as StringOutput: Stderr()\n\n    HRSystem as abstract\n      newWorkingWeek() as abstract\n\n      calculatePayroll() as abstract\n        -> outputInterface as OutputInterface\n\n      trackWork() as abstract\n        ->\n          outputInterface as OutputInterface\n          amountWorked as Duration\n\n      changeRole() as abstract\n        ->\n          employeeId as EmployeeId\n          newRole as RoleName\n\n      newStarter() as abstract\n        ->\n          person as Person\n          role as RoleName\n          payrollPolicy as PayrollPolicy\n\n    SimpleHRSystem is HRSystem\n      employeeDb as EmployeeDB?\n\n      default private SimpleHRSystem()\n\n      SimpleHRSystem()\n        -> employeeDb as EmployeeDB\n        this.employeeDb: employeeDb\n\n      override newWorkingWeek()\n        employed <- employeeDb.employed()\n        for employment in employed\n          employment.resetHoursWorked()\n\n      override calculatePayroll()\n        -> outputInterface as OutputInterface\n        payrollSystem <- PayrollSystem(outputInterface.output())\n        payrollSystem.calculatePayroll(employeeDb.employed())\n\n      override trackWork()\n        ->\n          outputInterface as OutputInterface\n          amountWorked as Duration\n        productivitySystem <- ProductivitySystem(outputInterface.output())\n        productivitySystem.track(employeeDb.employed(), amountWorked)\n\n      override changeRole()\n        ->\n          employeeId as EmployeeId\n          newRole as RoleName\n        require employeeId? and newRole?\n        employeeDb.changeRole(employeeId, newRole)\n\n      override newStarter()\n        ->\n          person as Person\n          role as RoleName\n          payrollPolicy as PayrollPolicy\n        require person? and role? and payrollPolicy?\n        employeeDb.addEmployee(person, role, payrollPolicy)\n\n      default operator ?\n\n  defines application\n\n    //Separation of what components/classes to use rather than what to do with them\n    DemoApp\n      employeeDb <- InMemoryEmployeeDB(InMemoryRoleDB(), InMemoryAddressDB(), InMemoryPayrollPolicyDB())\n\n      register SimpleHRSystem(employeeDb) as HRSystem\n      register StdoutInterface() as OutputInterface\n\n  defines program\n\n    //Separation of what functionality to provide with configuration supplied.\n    Demonstration() with application of DemoApp\n      hrSystem as HRSystem!\n      outputInterface as OutputInterface!\n\n      hrSystem.trackWork(outputInterface, PT40H)\n      hrSystem.calculatePayroll(outputInterface)\n\n      hrSystem.newWorkingWeek()\n      //Short week.\n      hrSystem.trackWork(outputInterface, PT32H)\n      hrSystem.calculatePayroll(outputInterface)","expectedOutput":"Tracking Employee Productivity\n==============================\nEmployee 1 - Mary Poppins: \n - screams and yells for 40 hours.\n\nEmployee 2 - John Smith: \n - does paperwork for 40 hours.\n\nEmployee 3 - Kevin Bacon: \n - expends 40 hours on the phone.\n\nEmployee 4 - Jane Doe: \n - manufactures gadgets for 40 hours.\n\nEmployee 5 - Robin Williams: \n - does paperwork for 40 hours.\n\n\nCalculating Payroll\n===================\nPayroll for: 1 - Mary Poppins\n- Check amount: 3000.00#USD\n- Sent to:\n121 Admin Rd.\nConcord NH 03301\n\nPayroll for: 2 - John Smith\n- Check amount: 1500.00#USD\n- Sent to:\n67 Paperwork Ave\nManchester NH 03101\n\nPayroll for: 3 - Kevin Bacon\n- Check amount: 1800.00#USD\n- Sent to:\n15 Rose St\nApt. B-1\nConcord NH 03301\n\nPayroll for: 4 - Jane Doe\n- Check amount: 600.00#USD\n- Sent to:\n39 Sole St.\nConcord NH 03301\n\nPayroll for: 5 - Robin Williams\n- Check amount: 360.00#USD\n- Sent to:\n99 Mountain Rd.\nConcord NH 03301\n\nTracking Employee Productivity\n==============================\nEmployee 1 - Mary Poppins: \n - screams and yells for 32 hours.\n\nEmployee 2 - John Smith: \n - does paperwork for 32 hours.\n\nEmployee 3 - Kevin Bacon: \n - expends 32 hours on the phone.\n\nEmployee 4 - Jane Doe: \n - manufactures gadgets for 32 hours.\n\nEmployee 5 - Robin Williams: \n - does paperwork for 32 hours.\n\n\nCalculating Payroll\n===================\nPayroll for: 1 - Mary Poppins\n- Check amount: 3000.00#USD\n- Sent to:\n121 Admin Rd.\nConcord NH 03301\n\nPayroll for: 2 - John Smith\n- Check amount: 1500.00#USD\n- Sent to:\n67 Paperwork Ave\nManchester NH 03101\n\nPayroll for: 3 - Kevin Bacon\n- Check amount: 1640.00#USD\n- Sent to:\n15 Rose St\nApt. B-1\nConcord NH 03301\n\nPayroll for: 4 - Jane Doe\n- Check amount: 480.00#USD\n- Sent to:\n39 Sole St.\nConcord NH 03301\n\nPayroll for: 5 - Robin Williams\n- Check amount: 288.00#USD\n- Sent to:\n99 Mountain Rd.\nConcord NH 03301\n\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"composition/composition_employees.ek9","url":"https://ek9.io/examples/composition/composition_employees.html","title":"Employees composed of a role and a payroll policy, delegated with by","code":"#!ek9\ndefines module site.composition.employees\n  defines trait\n\n    IRole\n      performDuties()\n        -> hours as Integer\n        <- activity as String?\n\n    IPayrollCalculator\n      trackWork()\n        -> hours as Integer\n      calculatePayroll()\n        <- amount as Money?\n\n  defines record\n    //Added support for type inference back in for fields/properties\n    //but only is default constructor or a literal\n    Address\n      street <- String()\n      street2 <- String()\n      city <- String()\n      state <- String()\n      zipcode <- String()\n\n      //Might allow default with matching number type and name of parameters.\n      Address()\n        ->\n          street as String\n          street2 as String\n          city as String\n          state as String\n          zipcode as String\n\n        this.street :=: street\n        this.street2 :=: street2\n        this.city :=: city\n        this.state :=: state\n        this.zipcode :=: zipcode\n\n      override operator ? as pure\n        <- rtn as Boolean: street? and city? and state? and zipcode?\n\n      operator $ as pure\n        <- rtn as String: String()\n        mainLocation <- `${city} ${state} ${zipcode}`\n\n        if street2?\n          rtn :=? `${street}\\n${street2}\\n${mainLocation}`\n        else\n          rtn :=? `${street}\\n${mainLocation}`\n\n\n  defines class\n\n    Employee with trait of IRole by role, IPayrollCalculator by payroll\n      id <- Integer()\n      name <- String()\n      address <- Address()\n      role as IRole?\n      payroll as IPayrollCalculator?\n\n      //You can make a default constructor unavailable if you wish\n      default private Employee()\n      //No body\n\n      //You could just use\n      //default Employee() + the paramaters and the ek9 compiler would do that implementation for you.\n      Employee()\n        ->\n          id as Integer\n          name as String\n          address as Address\n          role as IRole\n          payroll as IPayrollCalculator\n        this.id: id\n        this.name: name\n        this.address: address\n        this.role: role\n        this.payroll: payroll\n\n      work()\n        -> hours as Integer\n\n        stdout <- Stdout()\n        duties <- performDuties(hours)\n        stdout.println(`Employee ${this}:`)\n        stdout.println(` - ${duties}\\n`)\n        payroll.trackWork(hours)\n\n      address()\n        <- rtn as Address: address\n\n      operator $ as pure\n        <- rtn as String: `${$id} - ${name}`\n\n      default operator ?\n\n    AddressBook\n      employeeAddresses as Dict of (Integer, Address): {\n        1: Address(street: \"121 Admin Rd.\", street2: String(), city: \"Concord\", state: \"NH\", zipcode: \"03301\"),\n        2: Address(street: \"67 Paperwork Ave\", street2: String(), city: \"Manchester\", state: \"NH\", zipcode: \"03101\"),\n        3: Address(street: \"15 Rose St\", street2: \"Apt. B-1\", city: \"Concord\", state: \"NH\", zipcode: \"03301\"),\n        4: Address(street: \"39 Sole St.\", street2: String(), city: \"Concord\", state: \"NH\", zipcode: \"03301\"),\n        5: Address(street: \"99 Mountain Rd.\", street2: String(), city: \"Concord\", state: \"NH\", zipcode: \"03301\")\n        }\n\n      getEmployeeAddress()\n        -> employeeId as Integer\n        <- rtn as Address: employeeAddresses.getOrDefault(employeeId, Address())\n\n      default operator ?\n\n    ProductivitySystem\n      roles as Dict of (String, IRole): {\n        \"manager\": ManagerRole(),\n        \"secretary\": SecretaryRole(),\n        \"sales\": SalesRole(),\n        \"factory\": FactoryRole()\n        }\n\n      getRole()\n        -> roleId as String\n        <- rtn as IRole: roles.getOrDefault(roleId, FactoryRole())\n\n      track()\n        ->\n          employees as List of Employee\n          hours as Integer\n\n        stdout <- Stdout()\n        stdout.println(\"Tracking Employee Productivity\")\n        stdout.println(\"==============================\")\n        for employee in employees\n          employee.work(hours)\n        stdout.print(\"\\n\")\n      default operator ?\n\n    // Employee roles\n\n    ManagerRole with trait of IRole\n      override performDuties()\n        -> hours as Integer\n        <- activity as String: `screams and yells for ${hours} hours.`\n      default operator ?\n\n    SecretaryRole with trait of IRole\n      override performDuties()\n        -> hours as Integer\n        <- activity as String: `does paperwork for ${hours} hours.`\n      default operator ?\n\n    SalesRole with trait of IRole\n      override performDuties()\n        -> hours as Integer\n        <- activity as String: `expends ${hours} hours on the phone.`\n      default operator ?\n\n    FactoryRole with trait of IRole\n      override performDuties()\n        -> hours as Integer\n        <- activity as String: `manufactures gadgets for ${hours} hours.`\n      default operator ?\n\n    //Payroll classes\n\n    PayrollSystem\n      employeePolicies as Dict of (Integer, PayrollPolicy): {\n        1: SalaryPolicy(3000#USD),\n        2: SalaryPolicy(1500#USD),\n        3: CommissionPolicy(1000#USD, 100#USD),\n        4: HourlyPolicy(15#USD),\n        5: HourlyPolicy(9#USD)\n        }\n\n      getPolicy()\n        -> employeeId as Integer\n        <- rtn as PayrollPolicy: employeePolicies.getOrDefault(employeeId, HourlyPolicy(9#USD))\n\n      calculatePayroll()\n        -> employees as List of Employee\n        stdout <- Stdout()\n        stdout.println(\"Calculating Payroll\")\n        stdout.println(\"===================\")\n        for employee in employees\n          stdout.println(`Payroll for: ${employee}`)\n          stdout.println(`- Check amount: ${employee.calculatePayroll()}`)\n          if employee.address()?\n              stdout.println(`- Sent to:\\n${employee.address()}`)\n          stdout.print(\"\\n\")\n\n      default operator ?\n\n    PayrollPolicy with trait of IPayrollCalculator as abstract\n      hoursWorked as Integer: 0\n\n      override trackWork()\n        -> hours as Integer\n        hoursWorked += hours\n\n      hoursWorked()\n        <- hours as Integer: hoursWorked\n\n      default operator ?\n\n    HourlyPolicy extends PayrollPolicy\n      hourRate as Money: Money()\n\n      HourlyPolicy()\n        -> hourRate as Money\n        this.hourRate = hourRate\n\n      override calculatePayroll()\n        <- amount as Money: hourRate * hoursWorked()\n\n      default operator ?\n\n    SalaryPolicy extends PayrollPolicy as open\n      weeklySalary as Money: Money()\n\n      SalaryPolicy()\n        -> weeklySalary as Money\n        this.weeklySalary = weeklySalary\n\n      override calculatePayroll()\n        <- amount as Money: weeklySalary\n\n      default operator ?\n\n    CommissionPolicy extends SalaryPolicy\n      commissionPerSale as Money: Money()\n\n      CommissionPolicy()\n        ->\n          weeklySalary as Money\n          commissionPerSale as Money\n        super(weeklySalary)\n        this.commissionPerSale = commissionPerSale\n\n      override calculatePayroll()\n        <- amount as Money: super.calculatePayroll()\n        amount += commission()\n\n      private commission()\n        <- amount as Money: commissionPerSale/5.0 * hoursWorked()\n\n      default operator ?\n\n    // Part of the driver to create the employees\n\n    EmployeeDatabase\n      productivitySystem as ProductivitySystem: ProductivitySystem()\n      payrollSystem as PayrollSystem: PayrollSystem()\n      addresses as AddressBook: AddressBook()\n\n      employees()\n        <- rtn as List of Employee: List()\n\n        //You can use named variable if you prefer\n        rtn += createEmployee(id: 1, name: \"Mary Poppins\", theRole: \"manager\")\n        rtn += createEmployee(2, \"John Smith\", \"secretary\")\n        rtn += createEmployee(3, \"Kevin Bacon\", \"sales\")\n        rtn += createEmployee(4, \"Jane Doe\", \"factory\")\n        rtn += createEmployee(5, \"Robin Williams\", \"secretary\")\n\n      private createEmployee()\n        ->\n          id as Integer\n          name as String\n          theRole as String\n        <- //a bit of a mouth full, but you can use named parameters like this if you wish.\n          rtn as Employee: Employee(\n            id: id,\n            name: name,\n            address: addresses.getEmployeeAddress(id),\n            role: productivitySystem.getRole(theRole),\n            payroll: payrollSystem.getPolicy(id)\n            )\n\n      default operator ?\n\n  defines program\n\n    Demonstration()\n      productivitySystem <- ProductivitySystem()\n      payrollSystem <- PayrollSystem()\n\n      employeeDatabase <- EmployeeDatabase()\n      employees <- employeeDatabase.employees()\n\n      productivitySystem.track(employees, 40)\n      payrollSystem.calculatePayroll(employees)","expectedOutput":"Tracking Employee Productivity\n==============================\nEmployee 1 - Mary Poppins:\n - screams and yells for 40 hours.\n\nEmployee 2 - John Smith:\n - does paperwork for 40 hours.\n\nEmployee 3 - Kevin Bacon:\n - expends 40 hours on the phone.\n\nEmployee 4 - Jane Doe:\n - manufactures gadgets for 40 hours.\n\nEmployee 5 - Robin Williams:\n - does paperwork for 40 hours.\n\n\nCalculating Payroll\n===================\nPayroll for: 1 - Mary Poppins\n- Check amount: 3000.00#USD\n- Sent to:\n121 Admin Rd.\nConcord NH 03301\n\nPayroll for: 2 - John Smith\n- Check amount: 1500.00#USD\n- Sent to:\n67 Paperwork Ave\nManchester NH 03101\n\nPayroll for: 3 - Kevin Bacon\n- Check amount: 1800.00#USD\n- Sent to:\n15 Rose St\nApt. B-1\nConcord NH 03301\n\nPayroll for: 4 - Jane Doe\n- Check amount: 600.00#USD\n- Sent to:\n39 Sole St.\nConcord NH 03301\n\nPayroll for: 5 - Robin Williams\n- Check amount: 360.00#USD\n- Sent to:\n99 Mountain Rd.\nConcord NH 03301\n\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"constants/consolidated/constants_consolidated_constants.ek9","url":"https://ek9.io/examples/constants/consolidated/constants_consolidated_constants.html","title":"The module's constants, in one dedicated file","code":"#!ek9\ndefines module site.constants.consolidated\n\n  defines constant\n    MAX_RETRIES <- 3\n    DEFAULT_TIMEOUT <- 30\n    LOG_LEVEL <- \"DEBUG\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"constants/consolidated/constants_consolidated_networking.ek9","url":"https://ek9.io/examples/constants/consolidated/constants_consolidated_networking.html","title":"A file that only uses the constants","code":"#!ek9\ndefines module site.constants.consolidated\n\n  defines function\n\n    connectionTimeout() as pure\n      <- seconds as Integer: DEFAULT_TIMEOUT\n\n    retryPolicy() as pure\n      <- policy as String: `retry ${MAX_RETRIES} times, logging at ${LOG_LEVEL}`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"constants/consolidated/constants_consolidated_settings.ek9","url":"https://ek9.io/examples/constants/consolidated/constants_consolidated_settings.html","title":"A program in a third file of the module","code":"#!ek9\ndefines module site.constants.consolidated\n\n  defines program\n\n    ShowSettings()\n      stdout <- Stdout()\n      stdout.println(retryPolicy())\n      stdout.println(`timeout ${connectionTimeout()} seconds`)","expectedOutput":"retry 3 times, logging at DEBUG\ntimeout 30 seconds\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"constants/constants_introduction.ek9","url":"https://ek9.io/examples/constants/constants_introduction.html","title":"Constants of every literal type, used in the same module","code":"#!ek9\ndefines module site.constants.introduction\n\n  defines constant\n\n    limitNumberOfRetries <- true\n\n    updateErrorLog <- false\n\n    delimiter <- ':'\n\n    author <- \"Frank Jones\"\n\n    maxNumberOfRetries <- 10\n\n    minTemperatureAllowed <- -2\n\n    PI <- 3.142\n\n    bitMask <- 0b01110001\n\n    noon <- 12:00\n\n    justAfterNoon <- 12:00:01\n\n    //ISO 8601 i.e P[n]Y[n]M[n]DT[n]H[n]M[n]S\n    maxRenewalDuration <- P3Y2M6DT12H15M6S\n\n    twoYears <- P2Y\n\n    twoMonths <- P2M\n\n    minusTwoDays <- P-2D\n\n    twoHours <- PT2H\n\n    minusTwoHours <- PT-2H\n\n    twoMinutes <- PT2M\n\n    timeoutPeriod <- 250ms\n\n    newMillennium <- 2000-01-01\n\n    ek9CreatedDateTime <- 2018-01-31T01:30:00-05:00\n\n    maxPayment <- 300000#USD\n\n    defaultColour <- #AB6F2B\n\n    twoMeters <- 2m\n\n    matchSteves <- /[S|s]te(?:ven?|phen)/\n\n    //A comment\n    //And another\n\n  defines function\n\n    areaOfCircle()\n      -> diameter as Float\n      <- result as Float: PI * (diameter/2)^2\n\n    circumferenceOfCircle()\n      -> diameter as Float\n      <- result as Float: PI * diameter","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"constants/constants_qualified.ek9","url":"https://ek9.io/examples/constants/constants_qualified.html","title":"A constant from another module, fully qualified","code":"#!ek9\ndefines module site.constants.part.one\n  defines function\n\n    printPI()\n      Stdout().println($site.constants.introduction::PI)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"constants/constants_referenced.ek9","url":"https://ek9.io/examples/constants/constants_referenced.html","title":"A constant from another module, through references","code":"#!ek9\ndefines module site.constants.part.two\n  references\n    site.constants.introduction::PI\n\n  defines function\n\n    printPI()\n      Stdout().println($PI)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"constants/scattered/constants_scattered_config.ek9","url":"https://ek9.io/examples/constants/scattered/constants_scattered_config.html","title":"Constants scattered over three files of one module","code":"#!ek9\ndefines module bad.site.constants.scattered\n\n  defines constant\n    MAX_RETRIES <- 3","expectedOutput":null,"kind":"bad","errors":["E11066"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"constants/scattered/constants_scattered_logging.ek9","url":"https://ek9.io/examples/constants/scattered/constants_scattered_logging.html","title":"The third file with a constant","code":"#!ek9\ndefines module bad.site.constants.scattered\n\n  defines constant\n    LOG_LEVEL <- \"DEBUG\"","expectedOutput":null,"kind":"bad","errors":["E11066"],"validation":"a file of the error example constants/scattered/: compiled with the project's other files, it reports nothing itself, and the project fails with exactly the errors listed in errors (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"constants/scattered/constants_scattered_networking.ek9","url":"https://ek9.io/examples/constants/scattered/constants_scattered_networking.html","title":"The second file with a constant","code":"#!ek9\ndefines module bad.site.constants.scattered\n\n  defines constant\n    DEFAULT_TIMEOUT <- 30","expectedOutput":null,"kind":"bad","errors":["E11066"],"validation":"a file of the error example constants/scattered/: compiled with the project's other files, it reports nothing itself, and the project fails with exactly the errors listed in errors (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"coverage/report/coverage_report.ek9","url":"https://ek9.io/examples/coverage/report/coverage_report.html","title":"The same functions, with tests that reach them all","code":"#!ek9\ndefines module site.coverage.report\n\n  defines function\n\n    celsiusToFahrenheit() as pure\n      -> celsius as Float\n      <- fahrenheit as Float: celsius * 9.0 / 5.0 + 32.0\n\n    fahrenheitToCelsius() as pure\n      -> fahrenheit as Float\n      <- celsius as Float: (fahrenheit - 32.0) * 5.0 / 9.0\n\n    describe() as pure\n      -> celsius as Float\n      <- rtn as String: celsius < 0.0 <- \"freezing\" else \"not freezing\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"coverage/report/dev/coverage_report_tests.ek9","url":"https://ek9.io/examples/coverage/report/dev/coverage_report_tests.html","title":"Tests that reach every function and both branches","code":"#!ek9\ndefines module site.coverage.report.tests\n\n  references\n    site.coverage.report::celsiusToFahrenheit\n    site.coverage.report::describe\n    site.coverage.report::fahrenheitToCelsius\n\n  defines program\n\n    @Test\n    BoilingPoint()\n      assert celsiusToFahrenheit(100.0) == 212.0\n\n    @Test\n    RoundTrip()\n      assert fahrenheitToCelsius(celsiusToFahrenheit(37.0)) == 37.0\n\n    @Test\n    BothSidesOfFreezing()\n      assert describe(-5.0) == \"freezing\"\n      assert describe(20.0) == \"not freezing\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"coverage/shortfall/coverage_shortfall.ek9","url":"https://ek9.io/examples/coverage/shortfall/coverage_shortfall.html","title":"Three functions, of which the tests reach one","code":"#!ek9\ndefines module site.coverage.shortfall\n\n  defines function\n\n    celsiusToFahrenheit() as pure\n      -> celsius as Float\n      <- fahrenheit as Float: celsius * 9.0 / 5.0 + 32.0\n\n    fahrenheitToCelsius() as pure\n      -> fahrenheit as Float\n      <- celsius as Float: (fahrenheit - 32.0) * 5.0 / 9.0\n\n    describe() as pure\n      -> celsius as Float\n      <- rtn as String: celsius < 0.0 <- \"freezing\" else \"not freezing\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"coverage/shortfall/dev/coverage_shortfall_tests.ek9","url":"https://ek9.io/examples/coverage/shortfall/dev/coverage_shortfall_tests.html","title":"One test: it passes, and leaves most of the code untested","code":"#!ek9\ndefines module site.coverage.shortfall.tests\n\n  references\n    site.coverage.shortfall::celsiusToFahrenheit\n\n  defines program\n\n    @Test\n    BoilingPoint()\n      assert celsiusToFahrenheit(100.0) == 212.0","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"dependencyInjection/dependencyInjection_components_and_aspects.ek9","url":"https://ek9.io/examples/dependencyInjection/dependencyInjection_components_and_aspects.html","title":"Components injected by abstract base, with timing and logging aspects","code":"#!ek9\ndefines module site.dependencyInjection.componentsAndAspects\n\n  defines component\n\n    BaseConfiguration abstract\n      getFileStoreName() abstract\n        <- rtn as String?\n\n      default operator ?\n\n    Solution1 is BaseConfiguration\n      override getFileStoreName() as\n        <- rtn String: \"MainStore\"\n\n    Solution2 extends BaseConfiguration\n      override getFileStoreName() as\n        <- rtn as String: \"SecondaryStore\"\n\n    Solution3 extends BaseConfiguration\n      storeName as String: \"DefaultStore\"\n\n      override getFileStoreName() as\n        <- rtn as String: storeName\n\n      default operator ?\n\n  defines class\n\n    ConfigHandler\n      //This component will get injected\n      config as BaseConfiguration!\n\n      showConfigDetails()\n        stdout <- Stdout()\n        stdout.println(config.getFileStoreName())\n\n      default operator ?\n\n  defines function\n\n    checkConfigHandler()\n      stdout <- Stdout()\n      stdout.println(\"Will check config handler to see if file store name is available\")\n      configHandler <- ConfigHandler()\n      configHandler.showConfigDetails()\n\n  defines application\n\n    noAspectApp\n      register Solution1() as BaseConfiguration\n\n    firstApp\n      register FileLogger() as ILogger\n      register Solution1() as BaseConfiguration with aspect of TimerAspect(SystemClock()), LoggingAspect(\"DEBUG\")\n\n    secondApp\n      register FileLogger() as ILogger\n      register Solution2() as BaseConfiguration with aspect of LoggingAspect(\"WARN\")\n\n    thirdApp\n      register FileLogger() as ILogger\n      register Solution3() as BaseConfiguration with aspect of TimerAspect(SystemClock())\n\n  defines program\n\n    Program0 with application of noAspectApp\n      stdout <- Stdout()\n      stdout.println(\"Program0 functionality\")\n      checkConfigHandler()\n\n    Program1 with application of firstApp\n      stdout <- Stdout()\n      stdout.println(\"Program1 functionality\")\n      checkConfigHandler()\n\n    Program2 with application of secondApp\n      stdout <- Stdout()\n      stdout.println(\"Program2 functionality\")\n      checkConfigHandler()\n\n    Program3 with application of thirdApp\n      stdout <- Stdout()\n      stdout.println(\"Program3 functionality\")\n      checkConfigHandler()\n\n  defines component\n\n    ILogger as abstract\n      log() as abstract\n        ->\n          level as String\n          content as String\n\n      default operator ?\n\n    FileLogger extends ILogger\n      stdout as Stdout: Stdout()\n      override log() as\n        ->\n          level as String\n          content as String\n        //Just use Stdout for logging for this example.\n        stdout.println(`${level}: ${content}`)\n\n      default operator ?\n\n  defines class\n\n    LoggingAspect extends Aspect\n      loggingLevel as String?\n\n      LoggingAspect() as pure\n        this(\"WARN\")\n\n      LoggingAspect() as pure\n        -> level as String\n        this.loggingLevel :=? level\n\n      override beforeAdvice()\n        -> joinPoint as JoinPoint\n        <- rtn as PreparedMetaData: PreparedMetaData(joinPoint)\n        //Will be injected\n        logger as ILogger!\n        logger.log(loggingLevel, `Before ${joinPoint.componentName()} ${joinPoint.methodName()}`)\n\n      override afterAdvice()\n        -> preparedMetaData as PreparedMetaData\n        joinPoint <- preparedMetaData.joinPoint()\n        //Will be injected\n        logger as ILogger!\n        logger.log(loggingLevel, `After ${joinPoint.componentName()} ${joinPoint.methodName()}`)\n\n      default operator ?\n    TimerData extends PreparedMetaData\n      beforeOperation as Millisecond?\n\n      default private TimerData()\n\n      TimerData()\n        ->\n          millis as Millisecond\n          joinPoint as JoinPoint\n        super(joinPoint)\n        beforeOperation: millis\n\n      before()\n        <- rtn as Millisecond: beforeOperation\n\n      default operator ?\n      default operator $\n      default operator :=:\n\n    TimerAspect extends Aspect\n      clock as Clock?\n\n      default private TimerAspect()\n\n      TimerAspect()\n        -> clock as Clock\n        this.clock: clock\n\n      override beforeAdvice()\n        -> joinPoint as JoinPoint\n        <- rtn as TimerData: TimerData(clock.millisecond(), joinPoint)\n\n      //A handler for Aspect's 'afterAdvice() as dispatcher': it takes a TimerData, so it is a new overload, not an\n      //override (front-end rationalisation N06), and EK9 dispatches a TimerData to it.\n      afterAdvice()\n        -> timerData as TimerData\n        millisecondsTaken <- clock.millisecond() - timerData.before()\n        joinPoint <- timerData.joinPoint()\n        //Will be injected\n        logger as ILogger!\n        logger.log(\"INFO\", `${millisecondsTaken} Milliseconds for ${joinPoint.componentName()} ${joinPoint.methodName()}`)\n\n      default operator ?","expectedOutput":{"Program0":"Program0 functionality\nWill check config handler to see if file store name is available\nMainStore\n","Program1":"Program1 functionality\nWill check config handler to see if file store name is available\nDEBUG: Before site.dependencyInjection.componentsAndAspects::Solution1 getFileStoreName\nDEBUG: After site.dependencyInjection.componentsAndAspects::Solution1 getFileStoreName\nINFO: {{Millisecond}} Milliseconds for site.dependencyInjection.componentsAndAspects::Solution1 getFileStoreName\nMainStore\n","Program2":"Program2 functionality\nWill check config handler to see if file store name is available\nWARN: Before site.dependencyInjection.componentsAndAspects::Solution2 getFileStoreName\nWARN: After site.dependencyInjection.componentsAndAspects::Solution2 getFileStoreName\nSecondaryStore\n","Program3":"Program3 functionality\nWill check config handler to see if file store name is available\nINFO: {{Millisecond}} Milliseconds for site.dependencyInjection.componentsAndAspects::Solution3 getFileStoreName\nDefaultStore\n"},"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"dependencyInjection/dependencyInjection_transaction.ek9","url":"https://ek9.io/examples/dependencyInjection/dependencyInjection_transaction.html","title":"A Transaction acquired in a try, committed or rolled back","code":"#!ek9\ndefines module site.dependencyInjection.transaction\n\n  defines class\n\n    DatabaseTransaction with trait of Transaction\n      connectionName <- String()\n      committed <- false\n\n      DatabaseTransaction()\n        -> connectionName as String\n        this.connectionName: connectionName\n\n      execute()\n        -> statement as String\n        Stdout().println(`${connectionName}: ${statement}`)\n\n      override commit()\n        execute(\"COMMIT\")\n        committed: true\n\n      override rollback()\n        execute(\"ROLLBACK\")\n        committed: false\n\n      override isCommitted() as pure\n        <- rtn as Boolean: Boolean(committed)\n\n      default operator ?\n\n  defines function\n\n    updateRecords()\n      ->\n        txn as DatabaseTransaction\n        amount as Integer\n      txn.execute(`UPDATE accounts SET balance = ${amount}`)\n      if amount < 0\n        throw Exception(\"a balance cannot be negative\")\n\n  defines program\n\n    Demo()\n      stdout <- Stdout()\n      for amount in [100, -5]\n        try\n          -> txn <- DatabaseTransaction(\"primary-db\")\n          try\n            updateRecords(txn, amount)\n            txn.commit()\n          catch\n            -> ex as Exception\n            txn.rollback()\n            stdout.println(`Transaction failed: ${ex}`)","expectedOutput":"primary-db: UPDATE accounts SET balance = 100\nprimary-db: COMMIT\nprimary-db: UPDATE accounts SET balance = -5\nprimary-db: ROLLBACK\nTransaction failed: Exception: a balance cannot be negative\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"dynamicClasses/dynamicClasses_composition.ek9","url":"https://ek9.io/examples/dynamicClasses/dynamicClasses_composition.html","title":"Dynamic functions and dynamic classes composed by delegation","code":"#!ek9\ndefines module site.dynamicClasses.composition\n\n  defines trait\n\n    LenValidator\n      validateLength() as abstract\n        -> p as String\n        <- r as Boolean?\n\n    CharValidator\n      validateCharacters() as abstract\n        -> p as String\n        <- r as Boolean?\n\n    Validator\n      validate() as abstract\n        -> p as String\n        <- r as Boolean?\n\n  defines class\n\n    NoDollarValidator with trait of CharValidator\n      override validateCharacters()\n        -> p as String\n        <- r as Boolean: p? and p not contains \"$\"\n\n  defines function\n\n    discriminator() as abstract\n      -> s as String\n      <- rtn as Boolean?\n\n  defines program\n\n    Example()\n\n      min <- 9\n      max <- 40\n      prohibited <- \"@\"\n\n      gt <- (min) is discriminator as function\n        rtn: length s > min\n\n      lt <- (max) is discriminator\n        rtn: length s < max\n\n      val1 <- \"Some Value\"\n      require gt(val1) and lt(val1)\n      val2 <- \"Short\"\n      require not gt(val2) and lt(val2)\n      val3 <- \"1234567890123456789012345678901234567890Long\"\n      require gt(val3) and not lt(val3)\n\n      lenValidator <- CheckLength(gt, max) with trait of LenValidator as class\n        override validateLength()\n          -> p as String\n          <- r as Boolean: false\n          if p?\n            r := gt(p) and length p < max //So I can just use gt and lt or mix and match\n\n        default operator ?\n\n      require lenValidator.validateLength(val1)\n      require not lenValidator.validateLength(val2)\n      require not lenValidator.validateLength(val3)\n\n      checkContent <- CheckCharacter(prohibited) with trait of CharValidator\n        override validateCharacters()\n          -> p as String\n          <- r as Boolean: true\n          if p?\n            r: p not contains prohibited\n\n        default operator ?\n\n      val4 <- \"1234567890@not allowed\"\n\n      require checkContent.validateCharacters(val1)\n      require checkContent.validateCharacters(val2)\n      require checkContent.validateCharacters(val3)\n      require not checkContent.validateCharacters(val4)\n\n      validator1 <- (lenValidator, checkContent) with trait of LenValidator by lenValidator, CharValidator by checkContent\n        default operator ?\n\n      require validator1.validateCharacters(val1) and validator1.validateLength(val1)\n      require validator1.validateCharacters(val2) and not validator1.validateLength(val2)\n      require validator1.validateCharacters(val3) and not validator1.validateLength(val3)\n      require not validator1.validateCharacters(val4) and validator1.validateLength(val4)\n\n      validator2 <- (validator1, checkContent) with trait of Validator, LenValidator by validator1, CharValidator by checkContent\n        override validate()\n          -> p as String\n          <- r as Boolean: validateLength(p) and validateCharacters(p)\n\n        default operator ?\n\n      require validator2.validate(val1)\n      require not validator2.validate(val2)\n      require not validator2.validate(val3)\n      require not validator2.validate(val4)\n\n      val5 <- \"steve\"\n\n      validator3 <- (lenValidator) with trait of Validator, LenValidator by lenValidator, CharValidator by charValidator\n        charValidator as CharValidator: NoDollarValidator()\n\n        override validate()\n          -> p as String\n          <- r as Boolean: true\n          if p not matches /[S|s]te(?:ven?|phen)/\n            r: validateLength(p) and validateCharacters(p)\n\n        default operator ?\n\n      require validator3.validate(val1)\n      require not validator3.validate(val2)\n      require not validator3.validate(val3)\n      require validator3.validate(val4)\n      require validator3.validate(val5)\n\n      val6 <- \"steve#host\"\n\n      validator4 <- (lenValidator) with trait of Validator, LenValidator by lenValidator, CharValidator\n        notAllowed as String: \"#\"\n\n        override validate()\n          -> p as String\n          <- r as Boolean: validateLength(p) and validateCharacters(p)\n\n        override validateCharacters()\n          -> p as String\n          <- r as Boolean: false\n          if p?\n            r := p not contains notAllowed\n\n        default operator ?\n\n      require validator4.validate(val1)\n      require not validator4.validate(val2)\n      require not validator4.validate(val3)\n      require validator4.validate(val4)\n      require not validator4.validate(val5)\n      require not validator4.validate(val6)\n\n      Stdout().println(\"Every validator accepted and rejected as expected\")","expectedOutput":"Every validator accepted and rejected as expected\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"dynamicClasses/dynamicClasses_tuple.ek9","url":"https://ek9.io/examples/dynamicClasses/dynamicClasses_tuple.html","title":"A dynamic class defined, captured and used as a type","code":"#!ek9\ndefines module site.dynamicClasses.tuple\n\n  defines function\n    printer2()\n      -> personInfo as ATuple\n      Stdout().println(`${ personInfo } but I can access ${personInfo.name()} directly if I wish`)\n\n    //Note how we can just use 'ATuple' in a normal way by creating an instance of it.\n    getATuple()\n      <- rtn as ATuple: ATuple(\"John\", 1994-01-01, \"English\")\n\n  defines program\n    ShowTupleClass()\n\n      stdout <- Stdout()\n\n      name <- \"Steve\"\n      dateOfBirth <- 1970-01-01\n\n      //Just access a function that returns 'ATuple' - even though 'ATuple' is not defined yet!\n      tuple1 <- getATuple()\n\n      //Let's have an inferred List of 'ATuple' and put the first entry in.\n      tuples <- [tuple1]\n\n      //This is both a declaration of a new type 'ATuple' and the creation of an object of type 'ATuple'\n      //AND also indented is the implementation of 'ATuple'.\n      //Plus we can put this in a loop if we need to; 'ATuple' is only defined once!\n      for i in 1 ... 10\n\n        //Make the data up from base information and dynamic content.\n        firstName <- `${name}-${i}`\n        dob <- dateOfBirth + Duration(`P${i}M`)\n\n        //define, populate and get an object of that type\n        tuple <- ATuple(name: firstName, dob: dob, language: \"English\") as class\n\n          //We can also create new properties in the class directly if necessary\n          //Rather than just capture.\n          message as String: \"Dynamic: \"\n\n          //You can even define a range of different constructors if you wish.\n          //These are not automatically created, developer needs to define the 'interface'\n          //That way if the names of variables captured are refactored/renamed, the rest of the code\n          //using ATuple can stay the same.\n          ATuple()\n            ->\n              name as String\n              dob as Date\n              language as String\n\n            this.name = name\n            this.dob = dob\n            this.language = language\n\n          //Add in methods, hiding internal structure of object or meeting a trait type interface.\n          name()\n            <- rtn as String: name\n\n          operator $ as pure\n            <- rtn as String: `${message} ${name} ${dob} ${language}`\n          operator #^ as pure\n            <- rtn as String: $this\n\n          default operator ?\n\n        //OK now just add that new tuple into the List of ATuple\n        tuples += tuple\n\n      //Display all those tuples.\n      cat tuples > stdout\n\n      //just to demonstrate calling a function that has 'ATuple' as a parameter.\n      printer1(tuple1)\n      printer2(tuple1)\n      printer2(getATuple())\n\n  defines function\n    printer1()\n      -> tuple as ATuple\n      stdout <- Stdout()\n      stdout.println(`[ ${tuple} ] but I can access [ ${tuple.name()} ] directly if I wish`)","expectedOutput":"Dynamic:  John 1994-01-01 English\nDynamic:  Steve-1 1970-02-01 English\nDynamic:  Steve-2 1970-03-01 English\nDynamic:  Steve-3 1970-04-01 English\nDynamic:  Steve-4 1970-05-01 English\nDynamic:  Steve-5 1970-06-01 English\nDynamic:  Steve-6 1970-07-01 English\nDynamic:  Steve-7 1970-08-01 English\nDynamic:  Steve-8 1970-09-01 English\nDynamic:  Steve-9 1970-10-01 English\nDynamic:  Steve-10 1970-11-01 English\n[ Dynamic:  John 1994-01-01 English ] but I can access [ John ] directly if I wish\nDynamic:  John 1994-01-01 English but I can access John directly if I wish\nDynamic:  John 1994-01-01 English but I can access John directly if I wish\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"dynamicFunctions/dynamicFunctions_math.ek9","url":"https://ek9.io/examples/dynamicFunctions/dynamicFunctions_math.html","title":"Dynamic functions over an abstract function, with and without captures","code":"#!ek9\ndefines module site.dynamicFunctions.math\n\n  defines function\n\n    mathOperation() as pure abstract\n      ->\n        x as Float\n        y as Float\n      <-\n        result as Float?\n\n  defines program\n\n    DynamicMathExample1()\n      stdout <- Stdout()\n      stdout.println(\"Math Dynamic Operation Example1\")\n      fixedValue <- 9.8\n\n      // is/extends and 'as function' are just syntactic sugar, examples of each\n      // notice how the incoming and returning parameter names are inferred from mathOperation\n\n      addFunction <- () is mathOperation as pure function\n        result: x+y\n\n      subtractFunction <- () extends mathOperation as pure\n        result: x-y\n\n      divideFunction <- () is mathOperation pure\n        result: x/y\n\n      multiplyFunction <- () is mathOperation pure\n        result: x*y\n\n      specialFunction <- (fixedValue) is mathOperation pure\n        result: (x+fixedValue) * y^fixedValue\n\n      // common super of mathOperation is inferred and ops is a 'List of mathOperation'\n      ops <- [addFunction, subtractFunction, divideFunction, multiplyFunction, specialFunction]\n\n      for op in ops\n        stdout.println(`Result: ${op(21, 7)}`)\n\n    DynamicMathExample2()\n      stdout <- Stdout()\n      stdout.println(\"Math Dynamic Operation Example2\")\n      fixedValue <- 9.8\n\n      //Nearest EK9 gets to a lambda - wrap in parenthesis on single line.\n      //Notice the last entry - 'captures' fixedValue and can use it in the function body\n      ops <- [\n        () is mathOperation as pure (result: x+y),\n        () is mathOperation as pure (result: x-y),\n        () is mathOperation as pure (result: x/y),\n        () is mathOperation as pure (result: x*y),\n        (fixedValue) is mathOperation pure (result: (x+fixedValue) * y^fixedValue)\n        ]\n\n      for op in ops\n        stdout.println(`Result: ${op(21, 7)}`)\n\n    DynamicMathExample3()\n      stdout <- Stdout()\n      stdout.println(\"Math Dynamic Operation Example3\")\n      fixedValue <- 9.8\n\n      //Same example but uses an inline list in the for loop.\n      for op in [\n        () is mathOperation as pure (result: x+y),\n        () is mathOperation as pure (result: x-y),\n        () is mathOperation as pure (result: x/y),\n        () is mathOperation as pure (result: x*y),\n        (fixedValue) is mathOperation pure (result: (x+fixedValue) * y^fixedValue)\n        ]\n        stdout.println(`Result: ${op(21, 7)}`)","expectedOutput":{"DynamicMathExample1":"Math Dynamic Operation Example1\nResult: 28.0\nResult: 14.0\nResult: 3.0\nResult: 147.0\nResult: 5.895375993827891E9\n","DynamicMathExample2":"Math Dynamic Operation Example2\nResult: 28.0\nResult: 14.0\nResult: 3.0\nResult: 147.0\nResult: 5.895375993827891E9\n","DynamicMathExample3":"Math Dynamic Operation Example3\nResult: 28.0\nResult: 14.0\nResult: 3.0\nResult: 147.0\nResult: 5.895375993827891E9\n"},"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"enumerations/enumerations_cards.ek9","url":"https://ek9.io/examples/enumerations/enumerations_cards.html","title":"Card ranks and suits as enumerations, with their built-in operators","code":"#!ek9\ndefines module site.enumerations.cards\n\n  defines type\n\n    CardRank\n      Two\n      Three\n      Four\n      Five\n      Six\n      Seven\n      Eight\n      Nine\n      Ten\n      Jack\n      Queen\n      King\n      Ace\n\n    CardSuit\n      Hearts\n      Diamonds\n      Clubs\n      Spades\n\n  defines record\n\n    Card\n      rank as CardRank: CardRank()\n      suit as CardSuit: CardSuit()\n\n      Card()\n        ->\n          rank as CardRank\n          suit as CardSuit\n        this.rank: rank\n        this.suit: suit\n\n      override operator ? as pure\n        <- rtn as Boolean: rank? and suit?\n\n      operator $ as pure\n        <- rtn as String: `${rank} of ${suit}`\n\n      operator #^ as pure\n        <- rtn as String: `${this}`\n\n  defines function\n\n    cardCreator() as abstract\n      -> rank as CardRank\n      <- rtn as Card?\n\n    fullRankCreator()\n      -> suit as CardSuit\n      <- rtn as List of Card: cat CardRank\n        | map with (suit) is cardCreator (rtn: Card(rank, suit))\n        | collect as List of Card\n\n  defines program\n\n    ShowOperators()\n      stdout <- Stdout()\n\n      hearts <- CardSuit.Hearts\n      clubs <- CardSuit.Clubs\n\n      require hearts <> clubs\n\n      require hearts == #< clubs\n\n      require CardSuit.Spades == #> clubs\n\n      unknownSuit <- CardSuit()\n\n      require ~unknownSuit?\n\n      asString <- $hearts\n\n      require asString == \"Hearts\"\n\n      require hearts < clubs\n\n      require clubs <=> hearts > 0\n\n      invalidSuit <- CardSuit(\"NonSuch\")\n      require ~invalidSuit?\n\n      validSuit <- CardSuit(\"Clubs\")\n      require validSuit?\n\n      validRank <- CardRank(\"Ace\")\n      require validRank?\n\n      for rank in CardRank\n        message <- switch rank\n          <- rtn as String: String()\n          case CardRank.Ace\n            rtn: `Wow very lucky ${rank}`\n          case > CardRank.Ten\n            rtn: `Not too bad ${rank}`\n          case > CardRank.Five\n            rtn: `Oh dear me ${rank}`\n          default\n            rtn: `Not so lucky ${rank}`\n        stdout.println(message)\n\n    DeckOfPlayingCards()\n      stdout <- Stdout()\n\n      //List the four suits\n      stdout.println(\"Cat Suits\")\n      cat CardSuit > stdout\n\n      //List each of the Ranks\n      stdout.println(\"Cat Ranks\")\n      cat CardRank > stdout\n\n      stdout.println(\"With just a for loop\")\n      for suit in CardSuit\n        stdout.println($suit)\n\n      //If you wanted a list of suits\n      suits <- cat CardSuit | collect as List of CardSuit\n      stdout.println(`There are ${length suits} suits`)\n\n      stdout.println(\"Procedural Deck creation\")\n      for suit in CardSuit\n        for rank in CardRank\n          stdout.println(Card(rank, suit))\n\n      //Now make a full deck of cards.\n      stdout.println(\"Functional Deck creation\")\n\n      cat CardSuit | map with fullRankCreator | flatten > stdout","expectedOutput":{"ShowOperators":"Not so lucky Two\nNot so lucky Three\nNot so lucky Four\nNot so lucky Five\nOh dear me Six\nOh dear me Seven\nOh dear me Eight\nOh dear me Nine\nOh dear me Ten\nNot too bad Jack\nNot too bad Queen\nNot too bad King\nWow very lucky Ace\n","DeckOfPlayingCards":"Cat Suits\nHearts\nDiamonds\nClubs\nSpades\nCat Ranks\nTwo\nThree\nFour\nFive\nSix\nSeven\nEight\nNine\nTen\nJack\nQueen\nKing\nAce\nWith just a for loop\nHearts\nDiamonds\nClubs\nSpades\nThere are 4 suits\nProcedural Deck creation\nTwo of Hearts\nThree of Hearts\nFour of Hearts\nFive of Hearts\nSix of Hearts\nSeven of Hearts\nEight of Hearts\nNine of Hearts\nTen of Hearts\nJack of Hearts\nQueen of Hearts\nKing of Hearts\nAce of Hearts\nTwo of Diamonds\nThree of Diamonds\nFour of Diamonds\nFive of Diamonds\nSix of Diamonds\nSeven of Diamonds\nEight of Diamonds\nNine of Diamonds\nTen of Diamonds\nJack of Diamonds\nQueen of Diamonds\nKing of Diamonds\nAce of Diamonds\nTwo of Clubs\nThree of Clubs\nFour of Clubs\nFive of Clubs\nSix of Clubs\nSeven of Clubs\nEight of Clubs\nNine of Clubs\nTen of Clubs\nJack of Clubs\nQueen of Clubs\nKing of Clubs\nAce of Clubs\nTwo of Spades\nThree of Spades\nFour of Spades\nFive of Spades\nSix of Spades\nSeven of Spades\nEight of Spades\nNine of Spades\nTen of Spades\nJack of Spades\nQueen of Spades\nKing of Spades\nAce of Spades\nFunctional Deck creation\nTwo of Hearts\nThree of Hearts\nFour of Hearts\nFive of Hearts\nSix of Hearts\nSeven of Hearts\nEight of Hearts\nNine of Hearts\nTen of Hearts\nJack of Hearts\nQueen of Hearts\nKing of Hearts\nAce of Hearts\nTwo of Diamonds\nThree of Diamonds\nFour of Diamonds\nFive of Diamonds\nSix of Diamonds\nSeven of Diamonds\nEight of Diamonds\nNine of Diamonds\nTen of Diamonds\nJack of Diamonds\nQueen of Diamonds\nKing of Diamonds\nAce of Diamonds\nTwo of Clubs\nThree of Clubs\nFour of Clubs\nFive of Clubs\nSix of Clubs\nSeven of Clubs\nEight of Clubs\nNine of Clubs\nTen of Clubs\nJack of Clubs\nQueen of Clubs\nKing of Clubs\nAce of Clubs\nTwo of Spades\nThree of Spades\nFour of Spades\nFive of Spades\nSix of Spades\nSeven of Spades\nEight of Spades\nNine of Spades\nTen of Spades\nJack of Spades\nQueen of Spades\nKing of Spades\nAce of Spades\n"},"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"exceptions/exceptions_big_cats.ek9","url":"https://ek9.io/examples/exceptions/exceptions_big_cats.html","title":"Exceptions: try, catch, handle, finally, a dispatcher, try with resources and try guards","code":"#!ek9\ndefines module site.exceptions.bigCats\n\n  defines constant\n    missingFile <- \"MightNotExist.txt\"\n\n  defines type\n\n    BigCat\n      Lion\n      Tiger\n      WildCat\n      Leopard\n      Lynx\n\n  defines class\n\n    AnException extends Exception\n      supportingInformation <- String()\n\n      AnException()\n        ->\n          primaryReason as String\n          supportingInformation as String\n          exitCode as Integer\n        super(primaryReason, exitCode)\n        this.supportingInformation :=: supportingInformation\n\n      supportingInformation() as pure\n        <- rtn as String: supportingInformation\n\n      override operator $ as pure\n        <- rtn as String: `${reason()} ${supportingInformation()} exit code ${exitCode()}`\n\n      default operator ?\n      default operator $$\n\n    OtherException extends Exception\n      retryAfter <- DateTime()\n\n      OtherException()\n        ->\n          reason as String\n          retryAfter as DateTime\n        super(reason)\n        this.retryAfter :=: retryAfter\n\n      retryAfter() as pure\n        <- rtn as DateTime: retryAfter\n\n      override operator $ as pure\n        <- rtn as String: `${reason()} retry after ${$retryAfter()}`\n\n      default operator ?\n      default operator $$\n\n    ExceptionExample\n      clock as Clock: SystemClock()\n      deferProcessingUntilAfter <- DateTime()\n\n      default private ExceptionExample()\n\n      ExceptionExample()\n        -> clock as Clock\n        this.clock: clock\n\n      checkExceptionHandling()\n        -> aCat as BigCat\n        <- didProcess <- false\n\n        stdout <- Stdout()\n\n        try\n          if deferProcessing()\n            stdout.println(`Deferred until after ${deferProcessingUntilAfter} ${aCat} not processed`)\n          else\n            triggerResult <- triggerPossibleException(aCat)\n            stdout.println(triggerResult)\n            didProcess: true\n        catch\n          -> ex as Exception\n          stdout.println(handleException(ex))\n        finally\n          stdout.println(`Finished checking ${aCat}`)\n\n      triggerPossibleException()\n        -> aCat as BigCat\n        <- rtn as String: String()\n\n        switch aCat\n          case BigCat.Lion\n            throw Exception($aCat, 1)\n          case BigCat.Tiger\n            throw AnException(\"Too dangerous\", $aCat, 2)\n          case BigCat.WildCat, BigCat.Lynx\n            rtn: `Success with ${aCat}`\n          case BigCat.Leopard\n            throw OtherException($aCat, clock.dateTime() + PT2H)\n          default\n            rtn: `Success with ${aCat}`\n\n      deferProcessing()\n        <- rtn as Boolean: deferProcessingUntilAfter? <- deferProcessingUntilAfter > clock.dateTime() else false\n\n      private handleException() as dispatcher\n        -> ex as Exception\n        <- rtn as String: $ex\n\n      private handleException()\n        -> ex as AnException\n        <- rtn as String: $ex\n        if ex.exitCode()?\n          tidyUpReadyForProgramExit()\n\n      private handleException()\n        -> ex as OtherException\n        <- rtn as String: $ex\n        this.deferProcessingUntilAfter: ex.retryAfter()\n\n      private tidyUpReadyForProgramExit()\n        Stdout().println(\"Would tidy up any state ready for program exit\")\n\n      default operator ?\n\n    FileExceptionExample\n\n      demonstrateFileNotFound()\n        stdout <- Stdout()\n\n        //A failure while ACQUIRING a resource is not handled by the try that declares it;\n        //it goes to the enclosing try. Once acquired, a resource is always closed.\n        try\n          try\n            -> input <- openInput(missingFile)\n            cat input > stdout\n        //rather than use catch 'handle' can be used\n        handle\n          -> ex as Exception\n          stdout.println($ex)\n        finally\n          stdout.println(\"Automatically closed file if opened\")\n\n      demonstrateNamedFileNotFound()\n        -> fileName as String\n\n        mainResults <- try\n          -> input1 <- openInput(fileName)\n          <- rtn as List of String: cat input1 | collect as List of String\n\n        //Let the exceptions fly back - don't handle in here.\n        Stdout().println(`Main Results ${mainResults}`)\n\n      demonstrateFilesNotFound()\n\n        mainResults <- try\n          ->\n            input1 <- openInput(missingFile)\n            input2 <- openInput(\"AlsoMightNotExist.txt\")\n          <-\n            rtn as List of String: cat input1, input2 | collect as List of String\n\n        //Let the exceptions fly back - don't handle in here.\n        Stdout().println(`Main Results ${mainResults}`)\n\n  defines function\n\n    //A missing file is not an Exception in EK9: the TextFile is just unset.\n    //Here that is turned into an Exception, so the caller decides what it means.\n    openInput()\n      -> fileName as String\n      <- rtn as CloseableStringInput?\n\n      file <- TextFile(FileSystemPath().inCurrentWorkingDirectory(fileName))\n      if not file?\n        throw Exception(`File Not Found: ${fileName}`)\n      rtn: file.input()\n\n  defines program\n\n    TryCatchExample()\n      stdout <- Stdout()\n\n      //Rather than use SystemClock - simulate one so that date time can be altered.\n      //This is a way of doing a 'Fake'/'Stub'.\n      simulatedClock <- () with trait of Clock as class\n        currentDateTime as DateTime: 1971-02-01T12:00:00Z\n\n        override dateTime() as pure\n          <- rtn as DateTime: currentDateTime\n\n        override millisecond() as pure\n          <- rtn as Millisecond: Millisecond(0)\n\n        setCurrentDateTime()\n          -> newDateTime as DateTime\n          this.currentDateTime = newDateTime\n\n        override operator ? as pure\n          <- rtn <- true\n\n      //use the simulated clock\n      example1 <- ExceptionExample(simulatedClock)\n\n      for cat in BigCat\n        if example1.checkExceptionHandling(cat)\n          stdout.println(`Processing of ${cat} was completed`)\n        else\n          stdout.println(`Processing of ${cat} was NOT completed`)\n\n      //just try Lynx again\n      require not example1.checkExceptionHandling(BigCat.Lynx)\n\n      //alter the time just passed the retry after time.\n      simulatedClock.setCurrentDateTime(simulatedClock.dateTime() + PT2H1M)\n      //Now it should be processed.\n      require example1.checkExceptionHandling(BigCat.Lynx)\n\n      example2 <- FileExceptionExample()\n      example2.demonstrateFileNotFound()\n\n      try\n        example2.demonstrateFilesNotFound()\n      catch\n        -> ex as Exception\n        stdout.println(`TryCatchExample: ${ex}`)\n\n  defines function\n\n    knownFileName()\n      -> key as String\n      <- rtn as String: String()\n\n      if key == \"report\"\n        rtn: missingFile\n\n  defines program\n\n    TryWithGuard()\n      stdout <- Stdout()\n      someVar as String?\n      try someVar :=? knownFileName(\"unknown\")\n        stdout.println(\"TryWithGuard: the try body ran\")\n        FileExceptionExample().demonstrateNamedFileNotFound(someVar)\n      catch\n        -> ex as Exception\n        stdout.println(`TryWithGuard: ${ex}`)\n      stdout.println(\"TryWithGuard: carried on\")\n\n    TryWithAssignment()\n      stdout <- Stdout()\n      someVar as String?\n      try someVar: knownFileName(\"report\")\n        stdout.println(\"TryWithAssignment: the try body ran\")\n        FileExceptionExample().demonstrateNamedFileNotFound(someVar)\n      catch\n        -> ex as Exception\n        stdout.println(`TryWithAssignment: ${ex}`)\n\n    TryWithDeclaration()\n      stdout <- Stdout()\n\n      try someVar <- knownFileName(\"unknown\")\n        stdout.println(\"TryWithDeclaration: the try body ran\")\n        FileExceptionExample().demonstrateNamedFileNotFound(someVar)\n      catch\n        -> ex as Exception\n        stdout.println(`TryWithDeclaration: ${ex}`)\n\n      //This is a 'different' 'someVar' - the previous one is now out of scope.\n      someVar <- false\n      require someVar?\n      stdout.println(\"TryWithDeclaration: carried on\")","expectedOutput":{"TryCatchExample":"Exception: Lion: Exit Code: 1\nFinished checking Lion\nProcessing of Lion was NOT completed\nWould tidy up any state ready for program exit\nToo dangerous Tiger exit code 2\nFinished checking Tiger\nProcessing of Tiger was NOT completed\nSuccess with WildCat\nFinished checking WildCat\nProcessing of WildCat was completed\nLeopard retry after 1971-02-01T14:00:00Z\nFinished checking Leopard\nProcessing of Leopard was NOT completed\nDeferred until after 1971-02-01T14:00:00Z Lynx not processed\nFinished checking Lynx\nProcessing of Lynx was NOT completed\nDeferred until after 1971-02-01T14:00:00Z Lynx not processed\nFinished checking Lynx\nSuccess with Lynx\nFinished checking Lynx\nException: File Not Found: MightNotExist.txt\nAutomatically closed file if opened\nTryCatchExample: Exception: File Not Found: MightNotExist.txt\n","TryWithGuard":"TryWithGuard: carried on\n","TryWithAssignment":"TryWithAssignment: the try body ran\nTryWithAssignment: Exception: File Not Found: MightNotExist.txt\n","TryWithDeclaration":"TryWithDeclaration: carried on\n"},"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"exceptions/exceptions_suppressed.ek9","url":"https://ek9.io/examples/exceptions/exceptions_suppressed.html","title":"Reading the close failures suppressed onto an Exception","code":"#!ek9\ndefines module site.exceptions.suppressed\n\n  defines class\n\n    Part\n      name as String?\n\n      default private Part()\n\n      Part()\n        -> label as String\n        name: label\n\n      operator close as pure\n        stdout <- Stdout()\n        stdout.println(`closing ${name}`)\n        if name <> \"totals\"\n          throw Exception(`close of ${name} failed`)\n\n      default operator ?\n\n    Ledger\n      journal as Part: Part(\"journal\")\n      index as Part: Part(\"index\")\n      totals as Part: Part(\"totals\")\n\n      default operator close\n\n      default operator ?\n\n  defines function\n\n    report()\n      -> ex as Exception\n      Stdout().println(`caught: ${ex.reason()}`)\n      for failure in ex.suppressed()\n        describe(failure, \"  \")\n\n    describe()\n      ->\n        failure as Exception\n        indent as String\n      Stdout().println(`${indent}suppressed: ${failure.reason()}`)\n      for inner in failure.suppressed()\n        describe(inner, indent + \"  \")\n\n  defines program\n\n    InspectSuppressed()\n      stdout <- Stdout()\n\n      try\n        try\n          -> ledger <- Ledger()\n          stdout.println(\"using the ledger\")\n      catch\n        -> ex as Exception\n        report(ex)\n\n      try\n        try\n          -> ledger <- Ledger()\n          require ledger?\n          throw Exception(\"the posting failed\")\n      catch\n        -> ex as Exception\n        report(ex)\n\n      try\n        throw Exception(\"nothing to close\")\n      catch\n        -> ex as Exception\n        report(ex)\n        stdout.println(`nothing suppressed: ${length ex.suppressed() == 0}`)","expectedOutput":"using the ledger\nclosing totals\nclosing index\nclosing journal\ncaught: close of index failed\n  suppressed: close of journal failed\nclosing totals\nclosing index\nclosing journal\ncaught: the posting failed\n  suppressed: close of index failed\n    suppressed: close of journal failed\ncaught: nothing to close\nnothing suppressed: true\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_assignment_in_if.ek9","url":"https://ek9.io/examples/flowControl/flowControl_assignment_in_if.html","title":"If with an assignment, a guard or a declaration","code":"#!ek9\ndefines module site.flowControl.assignmentinif\n\n  defines constant\n    HOT_LIMIT <- 50\n    WARM_LIMIT <- 40\n    UNKNOWN_WARMTH <- \"Not sure where it might be warm\"\n\n  defines function\n\n    currentTemperature() as pure\n      -> country as String\n      <- temperature as Integer: Integer()\n\n      if country == \"GB\"\n        temperature :=? 20\n      else if country == \"DE\"\n        temperature :=? 41\n\n    assignmentInIf()\n      stdout <- Stdout()\n\n      //Note that this value is 'unset' in the sense it has no meaningful value\n      selectedTemperature <- Integer()\n\n      //See if we can find some hot temperature somewhere so in the US we have no idea! because value is unset\n      when selectedTemperature := currentTemperature(\"US\") with selectedTemperature > HOT_LIMIT\n        stdout.println(`Temp of ${selectedTemperature} a little warm in the US`)\n      else when selectedTemperature := currentTemperature(\"US\") with selectedTemperature < HOT_LIMIT\n        stdout.println(`Temp of ${selectedTemperature} not too bad in the US`)\n      else when selectedTemperature := currentTemperature(\"GB\") with selectedTemperature > WARM_LIMIT\n        stdout.println(`Temp of ${selectedTemperature} a little warm in the UK`)\n      else when selectedTemperature := currentTemperature(\"DE\") with selectedTemperature > WARM_LIMIT\n        stdout.println(`Temp of ${selectedTemperature} a little warm in the DE`)\n      else\n        stdout.println(UNKNOWN_WARMTH)\n\n    assignAndCheckInIf()\n      stdout <- Stdout()\n\n      selectedTemperature <- Integer()\n\n      //Here ':=' assigns, 'selectedTemperature?' checks for unset and only then does the further condition run\n      //Also note we can still use 'if' and rather than 'with' use 'then'\n      when selectedTemperature := currentTemperature(\"US\") then selectedTemperature? and (selectedTemperature > HOT_LIMIT)\n        stdout.println(`Temp of ${selectedTemperature} a little warm in the US`)\n      else when selectedTemperature := currentTemperature(\"US\") then selectedTemperature? and (selectedTemperature < HOT_LIMIT)\n        stdout.println(`Temp of ${selectedTemperature} not too bad in the US`)\n      else if selectedTemperature := currentTemperature(\"GB\") then selectedTemperature? and (selectedTemperature > WARM_LIMIT)\n        stdout.println(`Temp of ${selectedTemperature} a little warm in the UK`)\n      else when selectedTemperature := currentTemperature(\"DE\") then selectedTemperature? and (selectedTemperature > WARM_LIMIT)\n        stdout.println(`Temp of ${selectedTemperature} a little warm in the DE`)\n      else\n        stdout.println(UNKNOWN_WARMTH)\n\n    declarationInIf()\n      stdout <- Stdout()\n      when selectedTemperature <- currentTemperature(\"US\") with selectedTemperature > HOT_LIMIT\n        stdout.println(`Temp of ${selectedTemperature} a little warm in the US`)\n      else when selectedTemperature := currentTemperature(\"US\") then selectedTemperature? and (selectedTemperature < HOT_LIMIT)\n        stdout.println(`Temp of ${selectedTemperature} not too bad in the US`)\n      else if selectedTemperature := currentTemperature(\"GB\") with selectedTemperature > WARM_LIMIT\n        stdout.println(`Temp of ${selectedTemperature} a little warm in the UK`)\n      else when selectedTemperature: currentTemperature(\"DE\") then selectedTemperature > WARM_LIMIT\n        stdout.println(`Temp of ${selectedTemperature} a little warm in the DE`)\n      else\n        stdout.println(UNKNOWN_WARMTH)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_break.ek9","url":"https://ek9.io/examples/flowControl/flowControl_break.html","title":"A loop that tries to break out","code":"#!ek9\ndefines module bad.site.flowControl.breakloop\n\n  defines function\n\n    startsWithA() as pure\n      -> item as String\n      <- rtn as Boolean: item matches /^A.*/\n\n  defines program\n\n    FirstMatchWithBreak()\n      stdout <- Stdout()\n      items <- [\"Beta\", \"Alpha\", \"Avocado\"]\n\n      found <- false\n      for item in items\n        if startsWithA(item)\n          found: true\n          break\n      stdout.println(found)","expectedOutput":null,"kind":"bad","errors":["E01070"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"flowControl/flowControl_break_continue_alternatives.ek9","url":"https://ek9.io/examples/flowControl/flowControl_break_continue_alternatives.html","title":"Stream pipelines instead of break and continue","code":"#!ek9\ndefines module site.flowControl.breakcontinuealternatives\n\n  defines function\n\n    isMatch() as pure\n      -> item as String\n      <- rtn as Boolean: item matches /a.*/\n\n    isValid() as pure\n      -> item as String\n      <- rtn as Boolean: length item > 0\n\n    process()\n      -> item as String\n      Stdout().println(item)\n\n    //BAD: What you might write in other languages\n    //for item in items\n    //  if isMatch(item)\n    //    break  <- ERROR: E01070\n\n    //GOOD: EK9 stream pipeline\n    goodBreakAlternative()\n      -> items as List of String\n      <- result as List of String: cat items | filter by isMatch | head 1 | collect as List of String\n\n    //BAD: continue in other languages\n    //for item in items\n    //  if not isValid(item)\n    //    continue  <- ERROR: E01071\n    //  process(item)\n\n    //GOOD: EK9 stream pipeline\n    goodContinueAlternative()\n      -> items as List of String\n\n      //Filter out invalid items, process the rest\n      valid <- cat items | filter by isValid | collect as List of String\n      for item in valid\n        process(item)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_collections_pipeline.ek9","url":"https://ek9.io/examples/flowControl/flowControl_collections_pipeline.html","title":"Collections and iterators streamed, and tee","code":"#!ek9\ndefines module site.flowControl.collectionspipeline\n\n  defines program  \n    collectionsPipeLine()\n      stdout <- Stdout()\n\n      items <- [\"Alpha\", \"Beta\", \"Charlie\"]\n      cat items > stdout\n\n      //The alternative is when you already have an iterator\n      moreItems <- ['A', 'B', 'C']\n      iter <- moreItems.iterator()\n      cat iter > stdout\n\n      //An example of 'teeing' content out of a processing stream\n      capturedValues <- List() of String\n      cat [\"Alpha\", \"Beta\", \"Charlie\"], [\"Delta\", \"Echo\"] | tee in capturedValues > stdout\n      require capturedValues?","expectedOutput":"Alpha\nBeta\nCharlie\nA\nB\nC\nAlpha\nBeta\nCharlie\nDelta\nEcho\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_day_type.ek9","url":"https://ek9.io/examples/flowControl/flowControl_day_type.html","title":"Several case values in one case of a switch","code":"#!ek9\ndefines module site.flowControl.daytype\n\n  defines type\n\n    Day\n      MONDAY\n      TUESDAY\n      WEDNESDAY\n      THURSDAY\n      FRIDAY\n      SATURDAY\n      SUNDAY\n\n  defines function\n\n    dayTypeOf()\n      -> day as Day\n      <- dayType as String?\n\n      switch day\n        case Day.MONDAY, Day.TUESDAY, Day.WEDNESDAY, Day.THURSDAY, Day.FRIDAY\n          dayType: \"weekday\"\n        case Day.SATURDAY, Day.SUNDAY\n          dayType: \"weekend\"\n        default\n          dayType: \"unknown\"\n        // Automatic break - can't fall through\n\n  defines program\n\n    DayTypes()\n      stdout <- Stdout()\n      for day in Day\n        stdout.println(`${day} is a ${dayTypeOf(day)}`)","expectedOutput":"MONDAY is a weekday\nTUESDAY is a weekday\nWEDNESDAY is a weekday\nTHURSDAY is a weekday\nFRIDAY is a weekday\nSATURDAY is a weekend\nSUNDAY is a weekend\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_do_while.ek9","url":"https://ek9.io/examples/flowControl/flowControl_do_while.html","title":"Do/while loops, with a guard, and as an expression","code":"#!ek9\ndefines module site.flowControl.dowhile\n\n  defines function\n\n    collectionsDoWhileLoop()\n      stdout <- Stdout()\n\n      moreItems <- ['A', 'B', 'C']\n      itemIter <- moreItems.iterator()\n      if itemIter.hasNext()\n        do\n          item <- itemIter.next()\n          stdout.println(item)\n        while itemIter.hasNext()\n\n      //The above is a bit clumsy, so lets try this instead\n      //This has the same effect: a declaration guard skips even the first pass when the iterator is unset\n      do freshIter <- moreItems.iterator()\n        item <- freshIter.next()\n        stdout.println(item)\n      while freshIter.hasNext()\n\n    doLoopAsExpression()\n      limit <- 10\n      result <- do complete <- false\n        <- rtn <- 0\n        rtn++\n        complete: rtn == limit\n      while not complete\n\n      require result?\n\n      //Just to show that 'complete' is bound into the do/while scope\n      complete <- \"Almost\"\n      require complete?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_enum_switch.ek9","url":"https://ek9.io/examples/flowControl/flowControl_enum_switch.html","title":"Switching over an enumeration","code":"#!ek9\ndefines module site.flowControl.enumswitch\n\n  defines type\n\n    <?-\n      This is the enumeration that is used in the example below.\n      It is finite in the number of values it can hold.\n    -?>\n    LimitedEnum\n      A,\n      B,\n      C,\n      D\n\n  defines function\n\n    SimpleExhaustiveEnumerationExpressionSwitch()\n      -> selection as LimitedEnum\n\n      result <- switch selection\n        <- rtn as String?\n        case LimitedEnum.A\n          rtn: \"Just A\"\n        case LimitedEnum.B\n          rtn: \"Just B\"\n        case LimitedEnum.C\n          rtn: \"Just C\"\n        case LimitedEnum.D\n          rtn: \"Just D\"\n        default\n          rtn: \"Selection is not set\"\n\n      require result?\n\n  defines function\n\n    SimpleNonExhaustiveEnumerationExpressionSwitch()\n      -> selection as LimitedEnum\n\n      result <- switch selection\n        <- rtn as String?\n        case == LimitedEnum.A\n          rtn: \"Just A\"\n        default\n          rtn: \"Selection is anything but A\"\n\n      require result?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_first_match.ek9","url":"https://ek9.io/examples/flowControl/flowControl_first_match.html","title":"The first match through a stream pipeline","code":"#!ek9\ndefines module site.flowControl.firstmatch\n\n  defines function\n\n    startsWithA() as pure\n      -> item as String\n      <- rtn as Boolean: item matches /^A.*/\n\n  defines program\n\n    FirstMatch()\n      stdout <- Stdout()\n      items <- [\"Beta\", \"Alpha\", \"Avocado\"]\n\n      firstMatch <- cat items\n        | filter by startsWithA\n        | head 1\n        | collect as List of String\n      found <- not firstMatch.empty()\n      stdout.println(found)","expectedOutput":"true\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_for_collections.ek9","url":"https://ek9.io/examples/flowControl/flowControl_for_collections.html","title":"For loops over collections and iterators","code":"#!ek9\ndefines module site.flowControl.forcollections\n\n  defines function\n\n    CollectionsForLoop()\n      stdout <- Stdout()\n\n      stdout.println(\"Strings\")\n      for item in [\"Alpha\", \"Beta\", \"Charlie\"]\n        stdout.println(item)\n\n      stdout.println(\"Characters\")\n      //The alternative is when you already have an iterator\n      moreItems <- ['A', 'B', 'C']\n      for item in moreItems.iterator()\n        stdout.println(item)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_for_float_time.ek9","url":"https://ek9.io/examples/flowControl/flowControl_for_float_time.html","title":"For loops over Float and Time ranges","code":"#!ek9\ndefines module site.flowControl.forfloattime\n\n  defines function\n\n    FloatForLoop()\n      stdout <- Stdout()\n\n      //So you could do a calculation to get this value\n      incrementer <- 6.3\n      for i in 8.2 ... 30.0 by incrementer\n        stdout.println(`Value [${i}]`)\n\n      //descending\n      for i in 90.0 ... 70.0 by -5.0\n        stdout.println(`Value [${i}]`)\n\n    TimeForLoop()\n      stdout <- Stdout()\n\n      //From 9-5:30 every half hour\n      start <- Time().startOfDay() + PT9H\n      end <- Time().endOfDay() - PT6H30M\n      thirtyMinutes <- PT30M\n\n      //Be aware that time loops around.\n      for i in start ... end by thirtyMinutes\n        stdout.println(`Value [${i}]`)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_for_guards.ek9","url":"https://ek9.io/examples/flowControl/flowControl_for_guards.html","title":"For loops with a guard, an assignment and a declaration","code":"#!ek9\ndefines module site.flowControl.forguards\n\n  defines function\n\n    messagePrefix()\n      <- rtn <- \"SomePrefix-\"\n\n    forLoopWithGuard()\n      stdout <- Stdout()\n\n      prefix as String?\n      for prefix :=? messagePrefix() then i in 1 ... 10\n        stdout.println(`${prefix}${i}`)\n\n    forLoopWithAssignment()\n      stdout <- Stdout()\n\n      prefix as String?\n      for prefix: messagePrefix() then i in 1 ... 10\n        stdout.println(`${prefix}${i}`)\n\n    forLoopWithDeclaration()\n      stdout <- Stdout()\n\n      for prefix <- messagePrefix() then i in 1 ... 10\n        stdout.println(`${prefix}${i}`)\n\n      //Just to highlight that 'prefix' in the for loop - was scoped in the for loop only.\n      prefix <- 21\n      require prefix?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_for_loops.ek9","url":"https://ek9.io/examples/flowControl/flowControl_for_loops.html","title":"For loops over integer ranges","code":"#!ek9\ndefines module site.flowControl.forloops\n\n  defines function\n\n    ForLoopExample1\n      stdout <- Stdout()\n\n      for i in 1 ... 10\n        stdout.println(`Value [${i}]`)\n\n    ForLoopExample2\n      stdout <- Stdout()\n\n      for i in 0 ... 10 by 2\n        stdout.println(`Value [${i}]`)\n\n    ForLoopExample3\n      stdout <- Stdout()\n\n      j <- 2\n      for i in 0 ... 10 by j\n        stdout.println(`Value [${i}]`)\n\n    ForLoopExample4\n      stdout <- Stdout()\n\n      j <- -2\n      for i in 10 ... 0 by j\n        stdout.println(`Value [${i}]`)\n\n    ForLoopAsExpression()\n      result <- for i in 1 ... 10\n        <- rtn <- 0\n        rtn += i\n      require result?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_given_ternary.ek9","url":"https://ek9.io/examples/flowControl/flowControl_given_ternary.html","title":"given/when as an expression, and the ternary that replaces it","code":"#!ek9\ndefines module site.flowControl.giventernary\n\n  defines function\n    SimpleSwitchExampleWithTernaryAsAnAlternative()\n      -> conditionVariable as Boolean\n\n      //This is the reason that an ifExpression is not needed.\n      resultValue <- given conditionVariable\n        <- result String?\n        when true\n          result: \"Steve\"\n        default\n          result: \"Not Steve\"\n\n      require resultValue?\n\n      //But above could just have been a ternary\n      resultValue2 <- conditionVariable <- \"Steve\" else \"Not Steve\"\n      require resultValue2?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_guard_forms.ek9","url":"https://ek9.io/examples/flowControl/flowControl_guard_forms.html","title":"Declaration, assignment and assign-if-unset guards","code":"#!ek9\ndefines module site.flowControl.guardforms\n\n  defines constant\n    THRESHOLD <- 10\n    CACHE_LIMIT <- 100\n\n  defines class\n\n    Record\n      valid as Boolean: false\n\n      Record()\n        -> valid as Boolean\n        this.valid: valid\n\n      default Record()\n\n      isValid() as pure\n        <- rtn as Boolean: valid\n\n      default operator ?\n\n  defines function\n\n    getOptional()\n      <- rtn as Integer: 12\n\n    fetchData()\n      <- rtn as Record: Record(true)\n\n    compute()\n      <- rtn as Integer: 120\n\n  defines program\n\n    GuardForms()\n      stdout <- Stdout()\n\n      if value <- getOptional() with value > THRESHOLD\n        stdout.println(`declared ${value}`)\n\n      existing <- Record()\n      if existing := fetchData() then existing? and (existing.isValid())\n        stdout.println(\"fetched a valid record\")\n\n      cache <- Integer()\n      if cache :=? compute() with cache > CACHE_LIMIT\n        stdout.println(`cached ${cache}`)","expectedOutput":"declared 12\nfetched a valid record\ncached 120\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_if_else.ek9","url":"https://ek9.io/examples/flowControl/flowControl_if_else.html","title":"Simple if/else if/else, and the pure form","code":"#!ek9\ndefines module site.flowControl.ifelse\n\n  defines constant\n    UPPER_LIMIT <- 21\n    LOWER_LIMIT <- 10\n\n  defines function\n\n    testIfElseInteger()\n      -> first as Integer\n\n      trigger <- false\n\n      if first > UPPER_LIMIT\n        trigger: true\n      else if first < LOWER_LIMIT\n        trigger: false\n      else\n        trigger: Boolean()\n\n      //Just ensure referenced\n      require trigger?\n\n    testIfElseIntegerAsPure() as pure\n      -> first as Integer\n\n      trigger <- Boolean()\n\n      if first > UPPER_LIMIT\n        trigger :=? true\n      else if first < LOWER_LIMIT\n        trigger :=? false\n\n      //Just ensure referenced\n      require trigger?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_null_alternative.ek9","url":"https://ek9.io/examples/flowControl/flowControl_null_alternative.html","title":"An unset value and a guard instead of null","code":"#!ek9\ndefines module site.flowControl.nullalternative\n\n  defines function\n\n    getName() as pure\n      <- name as String: \"Steve\"\n\n    process() as pure\n      -> name as String\n      <- rtn as String: name.upperCase()\n\n    //BAD: null in other languages\n    //badNullUsage()\n    //  name <- null  <- ERROR: E01073\n\n    //GOOD: Create unset value\n    goodTriStateUsage()\n      name <- String()  //Unset\n      require not name?\n\n      //Guard checks if set\n      if validName <- getName()\n        stdout <- Stdout()\n        stdout.println(process(validName))  //Guaranteed set","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_range_check.ek9","url":"https://ek9.io/examples/flowControl/flowControl_range_check.html","title":"Checking a value is in a range","code":"#!ek9\ndefines module site.flowControl.rangecheck\n\n  defines constant\n    LIMIT <- 16\n    OFFSET <- 2\n\n  defines function\n\n    kotlinLikeRangeCheck()\n      ->\n        candidate as Integer\n        lowerBound as Integer\n        upperBound as Integer\n\n      stdout <- Stdout()\n\n      isWithin <- candidate in lowerBound ... upperBound\n      stdout.println(`${candidate} is within a range of ${lowerBound} ... ${upperBound}: ${isWithin}`)\n\n      isNotWithin <- candidate not in LIMIT - OFFSET ... upperBound - 1\n\n      stdout.println(`${candidate} is NOT within a range of ${LIMIT - OFFSET} ... ${upperBound - 1}: ${isNotWithin}`)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_require.ek9","url":"https://ek9.io/examples/flowControl/flowControl_require.html","title":"A pre-condition with require","code":"#!ek9\ndefines module site.flowControl.require\n\n  defines function\n\n    calculateSqrt()\n      -> radicand as Float\n      <- rtn as Float?\n\n      //This is a pre-condition contract. The function cannot accept a negative value.\n      require radicand >= 0.0\n\n      //... function logic\n      rtn: sqrt radicand","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_return_alternative.ek9","url":"https://ek9.io/examples/flowControl/flowControl_return_alternative.html","title":"A returning variable with a default instead of return","code":"#!ek9\ndefines module site.flowControl.returnalternative\n\n  defines function\n\n    transform() as pure\n      -> payload as String\n      <- result as String: payload.upperCase()\n\n    //BAD: Early return in other languages\n    //processData()\n    //  -> payload as String\n    //  <- result as String?\n    //  if not payload?\n    //    return \"\"  <- ERROR: E01072\n\n    //GOOD: Return declaration with default\n    goodReturnAlternative()\n      -> payload as String\n      <- result as String: String()  //Default value\n\n      if payload?\n        result: transform(payload)\n      //Compiler enforces all paths initialize result","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_simple_if.ek9","url":"https://ek9.io/examples/flowControl/flowControl_simple_if.html","title":"If with boolean logic, when, and chained else if","code":"#!ek9\ndefines module site.flowControl.simpleif\n\n  defines constant\n    LOW_LIMIT <- 10\n    HIGH_LIMIT <- 19\n    TARGET <- 9\n\n  defines function\n\n    currentTemperature() as pure\n      -> country as String\n      <- temperature as Integer: Integer()\n\n      if country == \"GB\"\n        temperature :=? 20\n      else if country == \"DE\"\n        temperature :=? 41\n\n    simpleIf()\n      -> valueToTest as Integer\n      stdout <- Stdout()\n\n      suitableValue <- String()\n\n      if valueToTest < LOW_LIMIT\n        stdout.println(`Value ${valueToTest} is less than ${LOW_LIMIT}`)\n\n      secondValue <- 21\n      specialCondition <- true\n\n      if valueToTest < LOW_LIMIT and secondValue > HIGH_LIMIT or specialCondition\n        stdout.println(\"Test OK\")\n\n      //The same logic as above - but in a different layout.\n      if valueToTest < LOW_LIMIT and\n      secondValue > HIGH_LIMIT or\n      specialCondition\n        stdout.println(\"Test OK\")\n\n      //Rather than use the keyword 'if' you can use 'when'\n      when valueToTest < LOW_LIMIT\n        stdout.println(`Value ${valueToTest} is less than ${LOW_LIMIT}`)\n\n      //As you would expect it is possible to chain if and else statements\n      if valueToTest > TARGET\n        suitableValue: \"Too High\"\n      else if valueToTest < TARGET\n        suitableValue: \"Too Low\"\n      else\n        suitableValue: \"Just Right\"\n\n      stdout.println(suitableValue)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_switch_expression.ek9","url":"https://ek9.io/examples/flowControl/flowControl_switch_expression.html","title":"A switch expression over a String","code":"#!ek9\ndefines module site.flowControl.switchexpression\n\n  defines function\n\n    ASwitchAsExpression() as pure\n      -> conditionVariable as String\n\n      //This is more like a chained if/else with expressions in the <i>case</i>\n      resultText <- switch conditionVariable\n        <- result String?\n        case 'D'\n          result :=? \"Inappropriate\"\n        case matches /[nN]ame/\n          result :=? \"Perfect\"\n        case > \"Gandalf\"\n          result :=? \"Moderate\"\n        case < \"Charlie\"\n          result :=? \"Very High\"\n        default\n          result :=? \"Suitable\"\n\n      require resultText?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_switch_guards.ek9","url":"https://ek9.io/examples/flowControl/flowControl_switch_guards.html","title":"A switch with a guard, an assignment and a declaration","code":"#!ek9\ndefines module site.flowControl.switchguards\n\n  defines constant\n    MODERATE <- \"Moderate\"\n    VERY_HIGH <- \"Very High\"\n    SLIGHTLY_HIGH <- \"Slightly High\"\n    PERFECT <- \"Perfect\"\n    SUITABLE <- \"Suitable\"\n\n  defines function\n\n    currentTemperature() as pure\n      -> country as String\n      <- temperature as Integer: Integer()\n\n      if country == \"GB\"\n        temperature :=? 20\n      else if country == \"DE\"\n        temperature :=? 41\n\n    ASwitchWithGuard()\n      temperature <- Integer()\n      multiplier <- 5\n      resultText <- switch temperature :=? currentTemperature(\"GB\") with temperature\n        <- result String: String()\n        case < 12\n          result: MODERATE\n        case > 10*multiplier\n          result: VERY_HIGH\n        case 25, 26, 27\n          result: SLIGHTLY_HIGH\n        case 21, 22, 23, 24\n          result: PERFECT\n        default\n          result: SUITABLE\n\n      require resultText?\n\n    ASwitchWithAssignment()\n      -> multiplier as Integer\n\n      temperature <- Integer()\n      resultText <- switch temperature := currentTemperature(\"GB\") with temperature\n        <- result String: String()\n        case < 12\n          result: MODERATE\n        case > 10*multiplier\n          result: VERY_HIGH\n        case 25, 26, 27\n          result: SLIGHTLY_HIGH\n        case 21, 22, 23, 24\n          result: PERFECT\n        default\n          result: SUITABLE\n\n      require resultText?\n\n    ASwitchWithDeclaration()\n      -> multiplier as Integer\n\n      resultText <- switch temperature <- currentTemperature(\"GB\") with temperature\n        <- result String: String()\n        case < 12\n          result: MODERATE\n        case > 10*multiplier\n          result: VERY_HIGH\n        case 25, 26, 27\n          result: SLIGHTLY_HIGH\n        case 21, 22, 23, 24\n          result: PERFECT\n        default\n          result: SUITABLE\n\n      require resultText?\n\n      //So this means the 'temperature' defined above is now out of scope and so\n      //can be declared a-fresh and used here\n      temperature <- \"Some other value\"\n      require temperature?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_switch_statement.ek9","url":"https://ek9.io/examples/flowControl/flowControl_switch_statement.html","title":"A switch statement with varied case matches","code":"#!ek9\ndefines module site.flowControl.switchstatement\n\n  defines function\n\n    currentTemperature() as pure\n      -> country as String\n      <- temperature as Integer: Integer()\n\n      if country == \"GB\"\n        temperature :=? 20\n      else if country == \"DE\"\n        temperature :=? 41\n\n    ASimpleSwitchStatement() as pure\n      -> conditionVariable as Integer\n      multiplier <- 5\n\n      //This is what we will vary based on the condition variable\n      resultText1 <- String()\n\n      switch conditionVariable\n        case < 12\n          resultText1 :=? \"Moderate\"\n        case > 10*multiplier\n          resultText1 :=? \"Very High\"\n        case 25, 26, 27\n          resultText1 :=? \"Slightly High\"\n        case currentTemperature(\"GB\"), 21, 22, 23, 24\n          resultText1 :=? \"Perfect\"\n        default\n          resultText1 :=? \"Not Suitable\"\n\n      require resultText1?\n\n      resultText2 <- String()\n      //The same switch could have been written using given and when\n      given conditionVariable\n        when < 12\n          resultText2 :=? \"Moderate\"\n        when > 10*multiplier\n          resultText2 :=? \"Very High\"\n        when 25, 26, 27\n          resultText2 :=? \"Slightly High\"\n        when currentTemperature(\"GB\"), 21, 22, 23, 24\n          resultText2 :=? \"Perfect\"\n        default\n          resultText2 :=? \"Not Suitable\"\n\n      require resultText2?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_time_pipeline.ek9","url":"https://ek9.io/examples/flowControl/flowControl_time_pipeline.html","title":"A time range streamed through a filter","code":"#!ek9\ndefines module site.flowControl.timepipeline\n\n  defines constant\n    LUNCH_START <- 12:00\n    LUNCH_END <- 14:00\n\n  defines function\n\n    workHours() as pure\n      -> time as Time\n      <- workTime as Boolean: time < LUNCH_START or time > LUNCH_END\n\n  defines program\n\n    TimePipeLine()\n      stdout <- Stdout()\n\n      //From 9-5:30 every half hour\n      start <- Time().startOfDay() + PT9H\n      end <- Time().endOfDay() - PT6H30M\n      thirtyMinutes <- PT30M\n\n      for i in start ... end by thirtyMinutes | filter by workHours > stdout","expectedOutput":"09:00:00\n09:30:00\n10:00:00\n10:30:00\n11:00:00\n11:30:00\n14:30:00\n15:00:00\n15:30:00\n16:00:00\n16:30:00\n17:00:00\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"flowControl/flowControl_while.ek9","url":"https://ek9.io/examples/flowControl/flowControl_while.html","title":"While loops, with guards, and as an expression","code":"#!ek9\ndefines module site.flowControl.while\n\n  defines function\n\n    collectionsWhileLoop()\n      stdout <- Stdout()\n\n      moreItems <- ['A', 'B', 'C']\n\n      stdout.println(\"Characters while\")\n      itemIter <- moreItems.iterator()\n      while itemIter.hasNext()\n        item <- itemIter.next()\n        stdout.println(item)\n\n      //Now re-point the iter from above to a fresh one, and check it is set\n      while itemIter := moreItems.iterator() then itemIter? and (itemIter.hasNext())\n        item <- itemIter.next()\n        stdout.println(item)\n\n      //Same again but with a blind assignment and only the condition\n      while itemIter := moreItems.iterator() then itemIter.hasNext()\n        item <- itemIter.next()\n        stdout.println(item)\n\n      //This time declare a new iterator, but within the while loop\n      while itemIterX <- moreItems.iterator() then itemIterX.hasNext()\n        item <- itemIterX.next()\n        stdout.println(item)\n\n    whileLoopAsExpression()\n      limit <- 10\n      result <- while complete <- false with not complete\n        <- rtn <- 0\n        rtn++\n        complete: rtn == limit\n      require result?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"forAI/forAI_dispatcher_after.ek9","url":"https://ek9.io/examples/forAI/forAI_dispatcher_after.html","title":"Dispatcher for type switching: the dispatcher version","code":"#!ek9\ndefines module site.forAI.dispatchafter\n\n  defines constant\n    PI <- 3.14159\n\n  defines class\n\n    Shape as abstract\n      default operator ?\n\n    Circle extends Shape\n      radius as Float: Float()\n\n      Circle()\n        -> radius as Float\n        this.radius :=: radius\n\n      radius() as pure\n        <- rtn as Float: radius\n\n      default operator ?\n\n    Square extends Shape\n      side as Float: Float()\n\n      Square()\n        -> side as Float\n        this.side :=: side\n\n      side() as pure\n        <- rtn as Float: side\n\n      default operator ?\n\n    Triangle extends Shape\n      base as Float: Float()\n      height as Float: Float()\n\n      Triangle()\n        ->\n          base as Float\n          height as Float\n        this.base :=: base\n        this.height :=: height\n\n      base() as pure\n        <- rtn as Float: base\n\n      height() as pure\n        <- rtn as Float: height\n\n      default operator ?\n\n    //A dispatcher is a METHOD - declare it in a class\n    AreaCalculator\n      calculateArea() as dispatcher\n        -> shape as Shape\n        <- area as Float: 0.0\n\n      calculateArea()\n        -> circle as Circle\n        <- area as Float: PI * circle.radius() * circle.radius()\n\n      calculateArea()\n        -> square as Square\n        <- area as Float: square.side() * square.side()\n\n      calculateArea()\n        -> triangle as Triangle\n        <- area as Float: 0.5 * triangle.base() * triangle.height()\n\n  defines program\n\n    Areas()\n      stdout <- Stdout()\n      calculator <- AreaCalculator()\n      shapes as List of Shape: [Square(2.0), Circle(2.0), Triangle(base: 3.0, height: 4.0)]\n      for shape in shapes\n        stdout.println($calculator.calculateArea(shape))","expectedOutput":"4.0\n12.56636\n6.0\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"forAI/forAI_dispatcher_before.ek9","url":"https://ek9.io/examples/forAI/forAI_dispatcher_before.html","title":"Dispatcher for type switching: the switch version","code":"#!ek9\ndefines module site.forAI.dispatchbefore\n\n  defines class\n\n    Shape\n      kind as String: String()\n      size as Float: Float()\n\n      Shape()\n        ->\n          kind as String\n          size as Float\n        this.kind :=: kind\n        this.size :=: size\n\n      type() as pure\n        <- rtn as String: kind\n\n      size() as pure\n        <- rtn as Float: size\n\n      default operator ?\n\n  defines function\n\n    calculateCircleArea() as pure\n      -> shape as Shape\n      <- area as Float: 3.14159 * shape.size() * shape.size()\n\n    calculateSquareArea() as pure\n      -> shape as Shape\n      <- area as Float: shape.size() * shape.size()\n\n    calculateTriangleArea() as pure\n      -> shape as Shape\n      <- area as Float: 0.5 * shape.size() * shape.size()\n\n    processShape()\n      -> shape as Shape\n      <- area as Float?\n\n      switch shape.type()\n        case \"circle\"\n          area: calculateCircleArea(shape)\n        case \"square\"\n          area: calculateSquareArea(shape)\n        case \"triangle\"\n          area: calculateTriangleArea(shape)\n        default\n          area: 0.0\n\n  defines program\n\n    AreaOfASquare()\n      stdout <- Stdout()\n      stdout.println($processShape(Shape(\"square\", 2.0)))","expectedOutput":"4.0\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"forAI/forAI_enum_operators.ek9","url":"https://ek9.io/examples/forAI/forAI_enum_operators.html","title":"An enumeration and the operators it is given","code":"#!ek9\ndefines module site.forAI.enumoperators\n\n  defines type\n    TrafficLight\n      Red\n      Amber\n      Green\n\n  defines program\n\n    TrafficLightOperators()\n      stdout <- Stdout()\n      light <- TrafficLight.Red\n\n      stdout.println($light)\n      stdout.println($$light)\n      stdout.println($ #< light)\n      stdout.println($ #> light)\n      stdout.println($ (light < TrafficLight.Green))\n      stdout.println($ TrafficLight(\"Blue\")?)\n      stdout.println($ (light == \"Red\"))\n      lights <- cat TrafficLight | collect as List of TrafficLight\n      stdout.println($lights)","expectedOutput":"Red\n\"Red\"\nRed\nGreen\ntrue\nfalse\ntrue\n[Red, Amber, Green]\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"forAI/forAI_guard_flattening_after.ek9","url":"https://ek9.io/examples/forAI/forAI_guard_flattening_after.html","title":"Guard flattening: the flattened version","code":"#!ek9\ndefines module site.forAI.guardsafter\n\n  defines class\n\n    Customer\n      credit as Boolean: false\n\n      Customer()\n        -> credit as Boolean\n        this.credit :=: credit\n\n      hasCredit() as pure\n        <- rtn as Boolean: credit\n\n      default operator ?\n\n    Order\n      reference as String: String()\n      customer as Customer: Customer()\n\n      Order()\n        ->\n          reference as String\n          customer as Customer\n        this.reference :=: reference\n        this.customer: customer\n\n      id() as pure\n        <- rtn as String: reference\n\n      isValid() as pure\n        <- rtn as Boolean: reference?\n\n      getCustomer() as pure\n        <- rtn as Customer: customer\n\n      default operator ?\n\n  defines function\n\n    processOrder()\n      -> order as Order\n      <- result as String: String()\n\n      if validateOrder(order)\n        result: \"Processing \" + order.id()\n\n    validateOrder() as pure\n      -> order as Order\n      <- valid as Boolean: false\n\n      if order? and order.isValid()\n        if customer <- order.getCustomer() with customer.hasCredit()\n          valid: true\n\n  defines program\n\n    ProcessOne()\n      stdout <- Stdout()\n      stdout.println(processOrder(Order(\"A-1\", Customer(true))))","expectedOutput":"Processing A-1\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"forAI/forAI_guard_flattening_before.ek9","url":"https://ek9.io/examples/forAI/forAI_guard_flattening_before.html","title":"Guard flattening: the nested version","code":"#!ek9\ndefines module site.forAI.guardsbefore\n\n  defines class\n\n    Customer\n      credit as Boolean: false\n\n      Customer()\n        -> credit as Boolean\n        this.credit :=: credit\n\n      hasCredit() as pure\n        <- rtn as Boolean: credit\n\n      default operator ?\n\n    Order\n      reference as String: String()\n      customer as Customer: Customer()\n\n      Order()\n        ->\n          reference as String\n          customer as Customer\n        this.reference :=: reference\n        this.customer: customer\n\n      id() as pure\n        <- rtn as String: reference\n\n      isValid() as pure\n        <- rtn as Boolean: reference?\n\n      getCustomer() as pure\n        <- rtn as Customer: customer\n\n      default operator ?\n\n  defines function\n\n    processOrder()\n      -> order as Order\n      <- result as String: String()\n\n      if order?\n        if order.isValid()\n          if customer <- order.getCustomer()\n            if customer.hasCredit()\n              result: \"Processing \" + order.id()\n\n  defines program\n\n    ProcessOne()\n      stdout <- Stdout()\n      stdout.println(processOrder(Order(\"A-1\", Customer(true))))","expectedOutput":"Processing A-1\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"forAI/forAI_idioms.ek9","url":"https://ek9.io/examples/forAI/forAI_idioms.html","title":"EK9 idioms: guards, coalescing, pipelines and dispatchers","code":"#!ek9\ndefines module site.forAI.idioms\n\n  defines function\n\n    getValue() as pure\n      <- rtn as String: \"ready\"\n\n    computeIfNeeded() as pure\n      <- rtn as String: \"computed\"\n\n    process()\n      -> status as String\n      Stdout().println(`Processing ${status}`)\n\n    isValid() as pure\n      -> item as Integer\n      <- rtn as Boolean: item > 0\n\n    transform() as pure\n      -> item as Integer\n      <- rtn as Integer: item * 2\n\n    useAGuard()\n      // Check and use in one expression\n      if result <- getValue()\n        process(result)\n\n    useCoalescing()\n      -> defaultValue as String\n      <- answer as String?\n      existingVar <- getValue()\n\n      // Use default if unset (?: - not ??, which only replaces an ABSENT value)\n      result <- getValue() ?: defaultValue\n\n      // Fill an unset variable (assign-if-unset - computeIfNeeded() runs only if needed)\n      existingVar :=? computeIfNeeded()\n\n      answer: `${result}\\n${existingVar}`\n\n    usePipeline()\n      -> items as List of Integer\n      <- answer as List of Integer?\n\n      // Transform and collect\n      result <- cat items\n        | filter by isValid\n        | map with transform\n        | collect as List of Integer\n\n      answer: result\n\n  defines class\n\n    Event as abstract\n      default operator ?\n\n    OrderPlaced extends Event\n      reference as String: String()\n\n      OrderPlaced()\n        -> reference as String\n        this.reference :=: reference\n\n      reference() as pure\n        <- rtn as String: reference\n\n      default operator ?\n\n    OrderCancelled extends Event\n      default operator ?\n\n    // A dispatcher is a METHOD - declare it in a class\n    Notifier\n      // Declare the dispatcher - its body is the fallback\n      describe() as dispatcher\n        -> event as Event\n        <- text as String: \"Unknown event\"\n\n      // Implement per concrete type\n      describe()\n        -> placed as OrderPlaced\n        <- text as String: `Order ${placed.reference()} placed`\n\n  defines program\n\n    Idioms()\n      stdout <- Stdout()\n      useAGuard()\n      stdout.println(useCoalescing(\"default\"))\n      stdout.println($usePipeline([-1, 1, 2]))\n\n      notifier <- Notifier()\n      events as List of Event: [OrderPlaced(\"A-1\"), OrderCancelled()]\n      for event in events\n        stdout.println(notifier.describe(event))","expectedOutput":"Processing ready\nready\nready\n[2, 4]\nOrder A-1 placed\nUnknown event\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"forAI/forAI_no_break_continue_return.ek9","url":"https://ek9.io/examples/forAI/forAI_no_break_continue_return.html","title":"What an AI will try: return, break and continue","code":"#!ek9\ndefines module bad.site.forAI.nobreak\n\n  defines constant\n    skipped <- 50\n\n  defines function\n\n    isMatch() as pure\n      -> item as String\n      <- rtn as Boolean: item?\n\n    firstMatch()\n      -> items as List of String\n      <- found as String: String()\n\n      for item in items\n        if isMatch(item)\n          return item  // ❌ No 'return'\n        break          // ❌ No 'break'\n\n    printAllBut()\n      stdout <- Stdout()\n\n      for i in 0 ... 100\n        if i == skipped\n          continue  // ❌ No 'continue'\n        stdout.println($i)","expectedOutput":null,"kind":"bad","errors":["E01072","E01070","E01071"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"forAI/forAI_quality_right.ek9","url":"https://ek9.io/examples/forAI/forAI_quality_right.html","title":"Code-quality rules an AI breaks: the correct forms","code":"#!ek9\ndefines module site.forAI.quality\n\n  defines function\n\n    createConnection()\n      ->\n        host as String\n        port as Integer\n        dbName as String\n        ssl as Boolean\n      <- connected as Boolean: host? and port? and dbName? and ssl?\n\n    lockAccount()\n      Stdout().println(\"Account locked\")\n\n    findAll() as pure\n      ->\n        pattern as RegEx\n        text as String\n      <- found as List of String: text.split(pattern)\n\n    checkIfEmpty() as pure\n      -> container as List of String\n      <- isEmpty as Boolean: container.empty()\n\n    calculateTotal() as pure\n      -> items as List of Float\n      <- total as Float: 0.0\n      cat items > total\n\n    welcome()\n      ->\n        name as String\n        city as String\n      <- greeting as String?\n      message <- `Hello ${name}, welcome to ${city}`\n      greeting: message\n\n    connect()\n      <- connected as Boolean?\n      connection <- createConnection(host: \"localhost\", port: 5432, dbName: \"mydb\", ssl: true)\n      connected: connection\n\n    guardLogin()\n      -> attempts as Integer\n      maxAttempts <- 3\n      if attempts > maxAttempts\n        lockAccount()\n\n    search()\n      ->\n        pattern as RegEx\n        text as String\n        container as List of String\n      <- summary as String?\n      foundItems <- findAll(pattern, text)\n      isEmpty <- checkIfEmpty(container)\n      summary: `${foundItems} ${isEmpty}`\n\n    addTax()\n      ->\n        items as List of Float\n        price as Float\n        tax as Float\n      <- summary as String?\n      total <- calculateTotal(items)\n      combined <- price + tax\n      summary: `${total} ${combined}`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"forAI/forAI_quality_wrong.ek9","url":"https://ek9.io/examples/forAI/forAI_quality_wrong.html","title":"Code-quality rules an AI breaks: the wrong forms","code":"#!ek9\ndefines module bad.site.forAI.quality\n\n  defines function\n\n    createConnection()\n      ->\n        host as String\n        port as Integer\n        dbName as String\n        ssl as Boolean\n      <- connected as Boolean: host? and port? and dbName? and ssl?\n\n    lockAccount()\n      Stdout().println(\"Account locked\")\n\n    findAll() as pure\n      ->\n        pattern as RegEx\n        text as String\n      <- found as List of String: text.split(pattern)\n\n    checkIfEmpty() as pure\n      -> container as List of String\n      <- isEmpty as Boolean: container.empty()\n\n    calculateTotal() as pure\n      -> items as List of Float\n      <- total as Float: 0.0\n      cat items > total\n\n    welcome()\n      ->\n        name as String\n        city as String\n      <- greeting as String?\n      message <- \"Hello \" + name + \", welcome to \" + city\n      greeting: message\n\n    connect()\n      <- connected as Boolean?\n      connection <- createConnection(\"localhost\", 5432, \"mydb\", true)\n      connected: connection\n\n    guardLogin()\n      -> attempts as Integer\n      if attempts > 3\n        lockAccount()\n\n    search()\n      ->\n        pattern as RegEx\n        text as String\n        container as List of String\n      <- summary as String?\n      matches <- findAll(pattern, text)\n      empty <- checkIfEmpty(container)\n      summary: `${matches} ${empty}`\n\n    addTax()\n      ->\n        items as List of Float\n        price as Float\n        tax as Float\n      calculateTotal(items)\n      price.+(tax)","expectedOutput":null,"kind":"bad","errors":["E11068","E11062","E11064","E11032","E11051","E11050"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"forAI/forAI_record_default_operators.ek9","url":"https://ek9.io/examples/forAI/forAI_record_default_operators.html","title":"A record asking for its operators with default operator","code":"#!ek9\ndefines module site.forAI.recordoperators\n\n  defines record\n    Customer\n      name as String: String()\n      email as String: String()\n\n      default operator $     //field-by-field toString\n      default operator $$    //field-by-field JSON\n      default operator #?    //field-by-field hashCode\n      default operator ?     //all-fields isSet\n      default operator <=>   //field-by-field comparison; == <> < <= > >= are generated from it\n      default operator :=:   //shallow copy: each field refers to the source's object\n\n  defines program\n\n    CustomerOperators()\n      stdout <- Stdout()\n      ada <- Customer()\n      ada.name: \"Ada\"\n      ada.email: \"ada@example.com\"\n      copy <- Customer()\n      copy :=: ada\n\n      stdout.println($ada)\n      stdout.println($$ada)\n      stdout.println($ ada?)\n      stdout.println($ (copy == ada))\n      stdout.println($ (ada < copy))","expectedOutput":"Customer(name=Ada, email=ada@example.com)\n{\"name\":\"Ada\",\"email\":\"ada@example.com\"}\ntrue\ntrue\nfalse\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"forAI/forAI_stream_replacement_after.ek9","url":"https://ek9.io/examples/forAI/forAI_stream_replacement_after.html","title":"Stream pipeline replacement: the pipeline version","code":"#!ek9\ndefines module site.forAI.streamsafter\n\n  defines class\n\n    User\n      name as String: String()\n      active as Boolean: false\n      recentLogin as Boolean: false\n\n      User()\n        ->\n          name as String\n          active as Boolean\n          recentLogin as Boolean\n        this.name :=: name\n        this.active :=: active\n        this.recentLogin :=: recentLogin\n\n      isActive() as pure\n        <- rtn as Boolean: active\n\n      hasRecentLogin() as pure\n        <- rtn as Boolean: recentLogin\n\n      operator $ as pure\n        <- rtn as String: name\n\n      default operator ?\n\n  defines function\n\n    findActiveUsers()\n      -> users as List of User\n      <- active as List of User?\n\n      active: cat users\n        | filter by isActiveWithRecentLogin\n        | collect as List of User\n\n    isActiveWithRecentLogin() as pure\n      -> user as User\n      <- result as Boolean: user.isActive() and user.hasRecentLogin()\n\n  defines program\n\n    ActiveUsers()\n      stdout <- Stdout()\n      users <- [\n        User(name: \"ada\", active: true, recentLogin: true),\n        User(name: \"bob\", active: true, recentLogin: false),\n        User(name: \"cy\", active: false, recentLogin: true)\n        ]\n      stdout.println($findActiveUsers(users))","expectedOutput":"[ada]\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"forAI/forAI_stream_replacement_before.ek9","url":"https://ek9.io/examples/forAI/forAI_stream_replacement_before.html","title":"Stream pipeline replacement: the loop version","code":"#!ek9\ndefines module site.forAI.streamsbefore\n\n  defines class\n\n    User\n      name as String: String()\n      active as Boolean: false\n      recentLogin as Boolean: false\n\n      User()\n        ->\n          name as String\n          active as Boolean\n          recentLogin as Boolean\n        this.name :=: name\n        this.active :=: active\n        this.recentLogin :=: recentLogin\n\n      isActive() as pure\n        <- rtn as Boolean: active\n\n      hasRecentLogin() as pure\n        <- rtn as Boolean: recentLogin\n\n      operator $ as pure\n        <- rtn as String: name\n\n      default operator ?\n\n  defines function\n\n    findActiveUsers()\n      -> users as List of User\n      <- active as List of User: List()\n\n      for user in users\n        if user.isActive()\n          if user.hasRecentLogin()\n            active += user\n\n  defines program\n\n    ActiveUsers()\n      stdout <- Stdout()\n      users <- [\n        User(name: \"ada\", active: true, recentLogin: true),\n        User(name: \"bob\", active: true, recentLogin: false),\n        User(name: \"cy\", active: false, recentLogin: true)\n        ]\n      stdout.println($findActiveUsers(users))","expectedOutput":"[ada]\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"forAI/forAI_streams_not_break.ek9","url":"https://ek9.io/examples/forAI/forAI_streams_not_break.html","title":"Stream pipelines instead of break and continue","code":"#!ek9\ndefines module site.forAI.streams\n\n  defines constant\n    skipped <- 50\n    shortest <- 5\n\n  defines function\n\n    isMatch() as pure\n      -> item as String\n      <- rtn as Boolean: item.length() >= shortest\n\n    notSkipped() as pure\n      -> i as Integer\n      <- rtn as Boolean: i <> skipped\n\n    process() as pure\n      -> i as Integer\n      <- rtn as String: `Item ${i}`\n\n  defines program\n\n    FirstMatch()\n      stdout <- Stdout()\n      items <- [\"a\", \"bb\", \"gamma\", \"delta\"]\n\n      // Use stream pipeline + head\n      result <- cat items\n        | filter by isMatch\n        | head 1        // First match\n        | collect as List of String\n\n      stdout.println($result)\n\n    AllButSkipped()\n      stdout <- Stdout()\n\n      // Use filter in pipeline - notSkipped and process are named functions\n      for i in 0 ... 100\n        | filter by notSkipped\n        | map with process\n        > stdout","expectedOutput":{"FirstMatch":"[\"gamma\"]\n","AllButSkipped":"Item 0\nItem 1\nItem 2\nItem 3\nItem 4\nItem 5\nItem 6\nItem 7\nItem 8\nItem 9\nItem 10\nItem 11\nItem 12\nItem 13\nItem 14\nItem 15\nItem 16\nItem 17\nItem 18\nItem 19\nItem 20\nItem 21\nItem 22\nItem 23\nItem 24\nItem 25\nItem 26\nItem 27\nItem 28\nItem 29\nItem 30\nItem 31\nItem 32\nItem 33\nItem 34\nItem 35\nItem 36\nItem 37\nItem 38\nItem 39\nItem 40\nItem 41\nItem 42\nItem 43\nItem 44\nItem 45\nItem 46\nItem 47\nItem 48\nItem 49\nItem 51\nItem 52\nItem 53\nItem 54\nItem 55\nItem 56\nItem 57\nItem 58\nItem 59\nItem 60\nItem 61\nItem 62\nItem 63\nItem 64\nItem 65\nItem 66\nItem 67\nItem 68\nItem 69\nItem 70\nItem 71\nItem 72\nItem 73\nItem 74\nItem 75\nItem 76\nItem 77\nItem 78\nItem 79\nItem 80\nItem 81\nItem 82\nItem 83\nItem 84\nItem 85\nItem 86\nItem 87\nItem 88\nItem 89\nItem 90\nItem 91\nItem 92\nItem 93\nItem 94\nItem 95\nItem 96\nItem 97\nItem 98\nItem 99\nItem 100\n"},"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"forAI/forAI_structure.ek9","url":"https://ek9.io/examples/forAI/forAI_structure.html","title":"The shape of a function and of a class","code":"#!ek9\ndefines module site.forAI.structure\n\n  defines function\n\n    lineTotal() as pure\n      ->\n        price as Float\n        quantity as Integer\n      <- total as Float?\n\n      //Assign the returning variable on every path\n      total: price * quantity\n\n  defines class\n    Account\n      owner as String?\n      balance as Float?\n\n      default private Account()\n\n      Account()\n        ->\n          owner as String\n          balance as Float\n        this.owner: owner\n        this.balance: balance\n\n      balanceAfter() as pure\n        -> deposit as Float\n        <- result as Float: balance + deposit\n\n      default operator ?\n\n  defines program\n\n    Structure()\n      stdout <- Stdout()\n      account <- Account(\"Ada\", 10.0)\n      stdout.println($lineTotal(2.5, 3))\n      stdout.println(`Ada: ${account.balanceAfter(5.0)}`)","expectedOutput":"7.5\nAda: 15.0\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"forAI/forAI_validation_chain_after.ek9","url":"https://ek9.io/examples/forAI/forAI_validation_chain_after.html","title":"Extract a validation chain: the extracted version","code":"#!ek9\ndefines module site.forAI.validationafter\n\n  defines class\n\n    User\n      authenticated as Boolean: false\n\n      User()\n        -> authenticated as Boolean\n        this.authenticated :=: authenticated\n\n      isAuthenticated() as pure\n        <- rtn as Boolean: authenticated\n\n      default operator ?\n\n    Request\n      user as User: User()\n      permissions as List of String: List()\n      payload as String: String()\n\n      Request()\n        ->\n          user as User\n          permissions as List of String\n          payload as String\n        this.user: user\n        this.permissions: permissions\n        this.payload :=: payload\n\n      hasUser() as pure\n        <- rtn as Boolean: user?\n\n      user() as pure\n        <- rtn as User: user\n\n      hasPermission() as pure\n        -> permission as String\n        <- rtn as Boolean: permission in permissions\n\n      payload() as pure\n        <- rtn as String: payload\n\n      default operator ?\n\n    Response\n      message as String: String()\n\n      Response() as pure\n        -> message as String\n        this.message :=: message\n\n      operator $ as pure\n        <- rtn as String: message\n\n      default operator ?\n\n  defines function\n\n    errorResponse() as pure\n      -> reason as String\n      <- response as Response: Response(reason)\n\n    doProcess() as pure\n      -> request as Request\n      <- response as Response: Response(`Processed ${request.payload()}`)\n\n    validateAndProcess()\n      -> request as Request\n      <- response as Response?\n\n      response: validateRequest(request) ?: doProcess(request)\n\n    validateRequest() as pure\n      -> request as Request\n      <- error as Response: checkNotNull(request)\n\n      //Assign-if-unset: each check runs only while no earlier check has failed\n      error :=? checkHasUser(request)\n      error :=? checkAuthenticated(request)\n      error :=? checkPermission(request, \"write\")\n      error :=? checkPayload(request)\n\n    checkNotNull() as pure\n      -> request as Request\n      <- error as Response: Response()\n      if not request?\n        error: errorResponse(\"Null request\")\n\n    checkHasUser() as pure\n      -> request as Request\n      <- error as Response: Response()\n      if not request.hasUser()\n        error: errorResponse(\"Missing user\")\n\n    checkAuthenticated() as pure\n      -> request as Request\n      <- error as Response: Response()\n      if not request.user().isAuthenticated()\n        error: errorResponse(\"Not authenticated\")\n\n    checkPermission() as pure\n      ->\n        request as Request\n        permission as String\n      <- error as Response: Response()\n      if not request.hasPermission(permission)\n        error: errorResponse(\"No permission\")\n\n    checkPayload() as pure\n      -> request as Request\n      <- error as Response: Response()\n      if not request.payload()?\n        error: errorResponse(\"Missing payload\")\n\n  defines program\n\n    Validate()\n      stdout <- Stdout()\n      allowed <- Request(user: User(true), permissions: [\"write\"], payload: \"data\")\n      refused <- Request(user: User(true), permissions: [\"read\"], payload: \"data\")\n      stdout.println($validateAndProcess(allowed))\n      stdout.println($validateAndProcess(refused))","expectedOutput":"Processed data\nNo permission\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"forAI/forAI_validation_chain_before.ek9","url":"https://ek9.io/examples/forAI/forAI_validation_chain_before.html","title":"Extract a validation chain: the else-if version","code":"#!ek9\ndefines module site.forAI.validationbefore\n\n  defines class\n\n    User\n      authenticated as Boolean: false\n\n      User()\n        -> authenticated as Boolean\n        this.authenticated :=: authenticated\n\n      isAuthenticated() as pure\n        <- rtn as Boolean: authenticated\n\n      default operator ?\n\n    Request\n      user as User: User()\n      permissions as List of String: List()\n      payload as String: String()\n\n      Request()\n        ->\n          user as User\n          permissions as List of String\n          payload as String\n        this.user: user\n        this.permissions: permissions\n        this.payload :=: payload\n\n      hasUser() as pure\n        <- rtn as Boolean: user?\n\n      user() as pure\n        <- rtn as User: user\n\n      hasPermission() as pure\n        -> permission as String\n        <- rtn as Boolean: permission in permissions\n\n      payload() as pure\n        <- rtn as String: payload\n\n      default operator ?\n\n    Response\n      message as String: String()\n\n      Response() as pure\n        -> message as String\n        this.message :=: message\n\n      operator $ as pure\n        <- rtn as String: message\n\n      default operator ?\n\n  defines function\n\n    errorResponse() as pure\n      -> reason as String\n      <- response as Response: Response(reason)\n\n    doProcess() as pure\n      -> request as Request\n      <- response as Response: Response(`Processed ${request.payload()}`)\n\n    validateAndProcess()\n      -> request as Request\n      <- response as Response?\n\n      if not request?\n        response: errorResponse(\"Null request\")\n      else if not request.hasUser()\n        response: errorResponse(\"Missing user\")\n      else if not request.user().isAuthenticated()\n        response: errorResponse(\"Not authenticated\")\n      else if not request.hasPermission(\"write\")\n        response: errorResponse(\"No permission\")\n      else if not request.payload()?\n        response: errorResponse(\"Missing payload\")\n      else\n        response: doProcess(request)\n\n  defines program\n\n    Validate()\n      stdout <- Stdout()\n      allowed <- Request(user: User(true), permissions: [\"write\"], payload: \"data\")\n      refused <- Request(user: User(true), permissions: [\"read\"], payload: \"data\")\n      stdout.println($validateAndProcess(allowed))\n      stdout.println($validateAndProcess(refused))","expectedOutput":"Processed data\nNo permission\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"forAI/shop/dev/forAI_order_tests.ek9","url":"https://ek9.io/examples/forAI/shop/dev/forAI_order_tests.html","title":"A unit test: arrange, act, assert","code":"#!ek9\ndefines module site.forAI.shop.ordertests\n\n  references\n    site.forAI.shop::Item\n    site.forAI.shop::Order\n\n  defines program\n\n    @Test\n    testOrderTotal()\n      // Arrange\n      order <- Order()\n      order.addItem(Item(\"Widget\", 10.00))\n      order.addItem(Item(\"Gadget\", 25.00))\n\n      // Act\n      total <- order.calculateTotal()\n\n      // Assert\n      assert total?\n      assert total == 35.00","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"forAI/shop/dev/forAI_validate_tests.ek9","url":"https://ek9.io/examples/forAI/shop/dev/forAI_validate_tests.html","title":"Unit tests with assertions","code":"#!ek9\ndefines module site.forAI.shop.validatetests\n\n  references\n    site.forAI.shop::validate\n\n  defines program\n\n    @Test\n    testValidateAcceptsLowerCase()\n      result <- validate(\"widget\")\n\n      assert result?\n      assert result\n\n    @Test\n    testValidateRejectsDigits()\n      result <- validate(\"widget42\")\n\n      assert result?\n      assert not result","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"forAI/shop/dev/formatting/forAI_format_test.ek9","url":"https://ek9.io/examples/forAI/shop/dev/formatting/forAI_format_test.html","title":"A black-box test: the output is the assertion","code":"#!ek9\ndefines module site.forAI.shop.formattests\n\n  references\n    site.forAI.shop::Formatter\n\n  defines program\n\n    @Test\n    testFormatOutput()\n      stdout <- Stdout()\n      formatter <- Formatter()\n      result <- formatter.format(\"hello\")\n      stdout.println(result)","expectedOutput":{"testFormatOutput":"HELLO\n"},"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"forAI/shop/dev/validation/forAI_validation_test.ek9","url":"https://ek9.io/examples/forAI/shop/dev/validation/forAI_validation_test.html","title":"A parameterized test: typed arguments from files","code":"#!ek9\ndefines module site.forAI.shop.validationtests\n\n  references\n    site.forAI.shop::validate\n\n  defines program\n\n    @Test\n    testValidation()\n      //The runtime parses dev/validation/commandline_arg_1.txt into the typed parameter\n      -> input as String\n      stdout <- Stdout()\n      result <- validate(input)\n      stdout.println($result)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"forAI/shop/forAI_shop.ek9","url":"https://ek9.io/examples/forAI/shop/forAI_shop.html","title":"The module the testing examples test","code":"#!ek9\ndefines module site.forAI.shop\n\n  defines function\n\n    validate() as pure\n      -> input as String\n      <- valid as Boolean: input matches /^[a-z]+$/\n\n  defines record\n\n    Item\n      name as String: String()\n      price as Float: Float()\n\n      Item()\n        ->\n          name as String\n          price as Float\n        this.name :=: name\n        this.price :=: price\n\n      default operator ?\n\n  defines class\n\n    Order\n      items as List of Item: List()\n\n      addItem()\n        -> item as Item\n        items += item\n\n      calculateTotal()\n        <- total as Float: 0.0\n        for item in items\n          total += item.price\n\n      default operator ?\n\n    Formatter\n      format() as pure\n        -> text as String\n        <- formatted as String: text.upperCase()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"functions/functions_abstract.ek9","url":"https://ek9.io/examples/functions/functions_abstract.html","title":"A function that is an abstract function","code":"#!ek9\ndefines module site.functions.abstractfunction\n\n  defines function\n  \n    mathOperation() as pure abstract\n      -> amount as Float\n      <- result as Float?\n\n    multiply() is mathOperation as pure\n      -> amount as Float\n      <- result as Float: amount * 5.6\n      \n  defines program\n    ShowAbstractFunction()\n      stdout <- Stdout()\n      \n      calculatedResult <- multiply(9)\n      stdout.println(`The result is ${calculatedResult}`)","expectedOutput":"The result is 50.4\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"functions/functions_higher_order.ek9","url":"https://ek9.io/examples/functions/functions_higher_order.html","title":"A higher order function returning a function delegate, and a dynamic function","code":"#!ek9\ndefines module site.functions.higherorder\n\n  defines constant\n    HEAVY_THRESHOLD <- 21\n\n  defines function\n\n    mathOperation() as pure abstract\n      -> amount as Float\n      <- result as Float?\n\n    multiply() is mathOperation as pure\n      -> amount as Float\n      <- result as Float: amount * 5.6\n\n    heavyMultiply() is mathOperation as pure\n      -> amount as Float\n      <- result as Float: amount * 7.99\n\n    suitableMathOperation()\n      -> amount as Float\n      <- op as mathOperation: amount < HEAVY_THRESHOLD <- heavyMultiply else multiply\n\n  defines program\n    ShowHighOrderFunction()\n      stdout <- Stdout()\n\n      amount <- 9\n      mathOp <- suitableMathOperation(amount)\n      calculatedResult <- mathOp(amount)\n      stdout.println(`The result is ${calculatedResult}`)\n\n      //Now a dynamic function example.\n      inlineFunction <- (\n        v1: 12,\n        v2: 64,\n        v3: 90\n        ) is mathOperation as pure (result: v1 + v2 + v3 * amount)\n\n      additionalCalculation <- inlineFunction(amount)\n      // 12 + 64 + 90*9\n      stdout.println(`The additional result is ${additionalCalculation}`)\n\n      value1 <- 9\n      value2 <- 30\n      chainedResult <- suitableMathOperation(value1)(value2)\n      stdout.println(`The chained result is ${chainedResult}`)","expectedOutput":"The result is 71.91\nThe additional result is 886.0\nThe chained result is 239.70000000000002\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"functions/functions_no_return.ek9","url":"https://ek9.io/examples/functions/functions_no_return.html","title":"There is no return: the '<-' returning variable","code":"#!ek9\ndefines module site.functions.noreturn\n\n  defines constant\n    noon <- 12\n    evening <- 18\n\n  defines function\n\n    //The initial value is the answer unless a later statement replaces it.\n    greeting() as pure\n      -> hour as Integer\n      <- rtn as String: \"Good evening\"\n\n      if hour < noon\n        rtn: \"Good morning\"\n      else if hour < evening\n        rtn: \"Good afternoon\"\n\n    //No initial value: the compiler proves that every path gives it one.\n    sign() as pure\n      -> amount as Integer\n      <- rtn as String?\n\n      if amount < 0\n        rtn: \"negative\"\n      else if amount > 0\n        rtn: \"positive\"\n      else\n        rtn: \"zero\"\n\n    //A switch returns a value through its own '<-' variable.\n    dayKind() as pure\n      -> day as String\n      <- rtn as String: switch day\n        <- kind as String?\n        case \"Saturday\", \"Sunday\"\n          kind: \"weekend\"\n        default\n          kind: \"weekday\"\n\n    lookup() as pure\n      -> code as String\n      <- rtn as String?\n\n      if code == \"GB\"\n        rtn: \"United Kingdom\"\n      else\n        rtn: String()\n\n    //A guard replaces the early return: the body runs only when lookup gives a set value,\n    //otherwise the initial value stands.\n    countryName() as pure\n      -> code as String\n      <- rtn as String: \"unknown\"\n\n      if name <- lookup(code)\n        rtn: name\n\n    isPositive() as pure\n      -> amount as Integer\n      <- rtn as Boolean: amount > 0\n\n    //A stream replaces a loop with 'continue' or 'break': 'filter' skips items ('head n' would stop\n    //early), and '>' adds each Integer into the returning variable.\n    sumOfPositives() as pure\n      -> amounts as List of Integer\n      <- rtn as Integer: 0\n\n      cat amounts | filter by isPositive > rtn\n\n  defines program\n\n    NoReturn()\n      stdout <- Stdout()\n\n      stdout.println(greeting(9))\n      stdout.println(greeting(20))\n      stdout.println(sign(-4))\n      stdout.println(sign(0))\n      stdout.println(dayKind(\"Sunday\"))\n      stdout.println(dayKind(\"Monday\"))\n      stdout.println(countryName(\"GB\"))\n      stdout.println(countryName(\"XX\"))\n      stdout.println($ sumOfPositives([-3, 0, 7, 2]))","expectedOutput":"Good morning\nGood evening\nnegative\nzero\nweekend\nweekday\nUnited Kingdom\nunknown\n9\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"functions/functions_no_return_keyword.ek9","url":"https://ek9.io/examples/functions/functions_no_return_keyword.html","title":"Writing 'return'","code":"#!ek9\ndefines module bad.site.functions.noreturn.keyword\n\n  defines function\n\n    sign() as pure\n      -> amount as Integer\n      <- rtn as String?\n\n      if amount < 0\n        return \"negative\"\n      return \"not negative\"","expectedOutput":null,"kind":"bad","errors":["E01072"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"functions/functions_no_return_missed_path.ek9","url":"https://ek9.io/examples/functions/functions_no_return_missed_path.html","title":"A returning variable a path never sets","code":"#!ek9\ndefines module bad.site.functions.noreturn.missedpath\n\n  defines function\n\n    sign() as pure\n      -> amount as Integer\n      <- rtn as String?\n\n      if amount < 0\n        rtn: \"negative\"\n      else if amount > 0\n        rtn: \"positive\"","expectedOutput":null,"kind":"bad","errors":["E08050"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"functions/functions_sanitized.ek9","url":"https://ek9.io/examples/functions/functions_sanitized.html","title":"Functions with sanitized parameters","code":"#!ek9\ndefines module site.functions.sanitized\n\n  defines function\n\n    executeQuery() as pure\n      -> sql as sanitized String\n      <- result as String: `Executing: ${sql}`\n      //The SQL is automatically sanitized before this function receives it\n\n    renderHtml() as pure\n      -> userContent as sanitized String\n      <- html as String: `<p>${userContent}</p>`\n      //XSS attacks are prevented by automatic sanitization","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"functions/functions_simple.ek9","url":"https://ek9.io/examples/functions/functions_simple.html","title":"A simple pure function","code":"#!ek9\ndefines module site.functions.simple\n\n  defines function\n    multiplier() as pure\n      <- value as Float: 5.6\n      \n  defines program\n    ShowSimpleFunction()\n      stdout <- Stdout()\n      \n      stdout.println(\"The multiplier is \" + $ multiplier())\n      \n      calculatedResult <- 6 * multiplier()\n      stdout.println(`The result is ${calculatedResult}`)","expectedOutput":"The multiplier is 5.6\nThe result is 33.599999999999994\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"generics/generics_constrained.ek9","url":"https://ek9.io/examples/generics/generics_constrained.html","title":"A generic function constrained by Shape: methods on T","code":"#!ek9\ndefines module site.generics.constrained\n\n  defines function\n    eventHandler of type T constrain by Shape\n      -> shape as T\n      require shape?\n      require shape.description()?\n      //any other 'method' on Shape can be used\n\n  defines class\n\n    Shape as abstract\n      description() as pure abstract\n        <- rtn as String?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"generics/generics_event_handlers.ek9","url":"https://ek9.io/examples/generics/generics_event_handlers.html","title":"A generic function and class constrained by a type","code":"#!ek9\ndefines module site.generics.eventHandlers\n\n  defines function\n\n    //Generic function - now open so can be extended once parameterized.\n    eventHandler of type T constrain by Shape as open\n      -> shape as T\n      require shape?\n      //Now it is possible access the 'description' method if needs be.\n      require shape.description()?\n\n  defines class\n\n    Text\n      mainValue as String?\n\n      default private Text() as pure\n\n      Text() as pure\n        -> content as String\n        mainValue:=? String(content)\n\n      mainValue() as pure\n        <- rtn as String: String(mainValue)\n\n      default operator ?\n\n    Shape as abstract\n      shapeInfo as String?\n\n      default private Shape() as pure\n\n      Shape() as pure\n        -> info as String\n        shapeInfo:=? String(info)\n\n      description() as pure\n        <- rtn as String: String(shapeInfo)\n\n      override operator ? as pure\n        <- rtn as Boolean: shapeInfo?\n\n    Circle is Shape\n\n      private Circle() as pure\n        -> info as String\n        //Must chain to an accessible initialising super - Shape's no-arg default is private (E07176).\n        super(info)\n\n      Circle() as pure\n        super(\"Circle\")\n\n      roundness() as pure\n        <- rtn as Float: 0.0\n\n    Square is Shape\n\n      private Square() as pure\n        -> info as String\n        //Must chain to an accessible initialising super - Shape's no-arg default is private (E07176).\n        super(info)\n\n      Square() as pure\n        super(\"Square\")\n\n  defines program\n\n    ExampleDriver1()\n      stdout <- Stdout()\n      stdout.println(\"Driver for generic event handler\")\n      eventProcessor <- ShapeEventProcessor()\n\n      //This is not allowed because eventHandler is constrained to Shape\n      //textHandler <- (eventProcessor) is eventHandler of Text\n\n      //Setup some event handlers and an example\n      //Process through 'Shape'\n      shapeHandler <- (eventProcessor) is eventHandler of Shape as function\n        eventProcessor.processShapeEvent(shape)\n\n      //Now type safe via generics and direct call to specific method\n      circleHandler <- (eventProcessor) is eventHandler of Circle as function\n        //Note strict typing means method 'roundness' is accessible.\n        Stdout().println(\"Roundness \" + $shape.roundness())\n        eventProcessor.processCircleEvent(shape)\n\n      //While handler is specific to Square can still call via processShapeEvent\n      squareHandler <- (eventProcessor) is eventHandler of Square as function\n        eventProcessor.processShapeEvent(shape)\n\n      //make some calls on the event handlers\n      shapeHandler(Circle())\n      shapeHandler(Square())\n\n      circleHandler(Circle())\n      squareHandler(Square())\n\n      //Will not compile - which is correct!\n      //circleHandler(Square())\n      //squareHandler(Circle())\n\n  defines class\n    //non-generic processor\n    ShapeEventProcessor\n      stdout as Stdout: Stdout()\n\n      processShapeEvent()\n        -> shape as Shape\n        require shape?\n        stdout.println(`Processed shape [${shape.description()}]`)\n\n      processCircleEvent()\n        -> circle as Circle\n        require circle?\n        stdout.println(`Processed circle [${circle.description()} roundness ${$circle.roundness()}]`)\n\n      default operator ?\n\n  defines program\n\n    ExampleDriver2()\n      stdout <- Stdout()\n      stdout.println(\"Driver for generic event handler and generic processor\")\n\n      eventProcessor as GenericShapeEventProcessor of Shape: GenericShapeEventProcessor()\n\n      shapeHandler <- (eventProcessor) is eventHandler of Shape as function\n        eventProcessor.processShapeEvent(shape)\n\n      //make some calls on the event handler\n      shapeHandler(Circle())\n      shapeHandler(Square())\n\n  defines class\n\n    GenericShapeEventProcessor of type T constrain by Shape\n      stdout as Stdout: Stdout()\n\n      default GenericShapeEventProcessor()\n\n      GenericShapeEventProcessor()\n        -> shape as T\n        require shape?\n\n      processShapeEvent()\n        -> shape as T\n        require shape?\n        stdout.println(`Processed shape [${shape.description()}]`)\n\n      default operator ?","expectedOutput":{"ExampleDriver1":"Driver for generic event handler\nProcessed shape [Circle]\nProcessed shape [Square]\nRoundness 0.0\nProcessed circle [Circle roundness 0.0]\nProcessed shape [Square]\n","ExampleDriver2":"Driver for generic event handler and generic processor\nProcessed shape [Circle]\nProcessed shape [Square]\n"},"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"generics/generics_list_of_circle.ek9","url":"https://ek9.io/examples/generics/generics_list_of_circle.html","title":"A List of Circle passed where a List of Shape is wanted","code":"#!ek9\ndefines module bad.site.generics.listOfCircle\n\n  defines class\n\n    Shape as abstract\n      shapeName() as pure abstract\n        <- rtn as String?\n\n    Circle extends Shape\n      override shapeName() as pure\n        <- rtn as String: \"circle\"\n\n  defines function\n\n    countShapes() as pure\n      -> shapes as List of Shape\n      <- rtn as Integer: length shapes\n\n  defines program\n\n    PassingCircles()\n      circles <- [Circle(), Circle()]\n      Stdout().println(countShapes(circles))","expectedOutput":null,"kind":"bad","errors":["E06270"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"generics/generics_separate_types.ek9","url":"https://ek9.io/examples/generics/generics_separate_types.html","title":"Methods overloaded on differently parameterised Lists","code":"#!ek9\ndefines module site.generics.separateTypes\n\n  defines class\n\n    Shape as abstract\n      shapeName() as pure abstract\n        <- rtn as String?\n\n    Circle extends Shape\n      override shapeName() as pure\n        <- rtn as String: \"circle\"\n\n    Square extends Shape\n      override shapeName() as pure\n        <- rtn as String: \"square\"\n\n    SimpleExample as abstract\n      assimilate() as pure abstract\n        -> items as List of Shape\n        <- rtn as Shape?\n\n      assimilate() as pure abstract\n        -> items as List of Circle\n        <- rtn as Shape?\n\n      assimilate() as pure abstract\n        -> items as List of Square\n        <- rtn as Shape?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"generics/generics_unconstrained.ek9","url":"https://ek9.io/examples/generics/generics_unconstrained.html","title":"An unconstrained generic function: only operators on T","code":"#!ek9\ndefines module site.generics.unconstrained\n\n  defines function\n    eventHandler of type T\n      -> shape as T\n      require shape?\n      //any other 'operator' on T can be used","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"inheritance/inheritance_closed_animal.ek9","url":"https://ek9.io/examples/inheritance/inheritance_closed_animal.html","title":"Extending a class that is not open","code":"#!ek9\ndefines module bad.site.inheritance.closedanimal\n\n  defines class\n\n    Animal\n      name as String: String()\n\n      speak()\n        Stdout().println(\"Generic animal sound\")\n\n      default operator ?\n\n    Dog extends Animal\n      // Animal is not open to be extended\n      override speak()\n        Stdout().println(\"Woof!\")","expectedOutput":null,"kind":"bad","errors":["E05030"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"inheritance/inheritance_closed_list.ek9","url":"https://ek9.io/examples/inheritance/inheritance_closed_list.html","title":"Extending List, which is not open","code":"#!ek9\ndefines module bad.site.inheritance.closedlist\n\n  defines class\n\n    MyList extends List of String\n      // List is not open to be extended\n      additionalMethod() as pure\n        <- rtn as Boolean: true","expectedOutput":null,"kind":"bad","errors":["E05030"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"inheritance/inheritance_composed_list.ek9","url":"https://ek9.io/examples/inheritance/inheritance_composed_list.html","title":"Composing a List instead of extending it","code":"#!ek9\ndefines module site.inheritance.composedlist\n\n  defines class\n\n    MyList\n      items as List of String: List()  // Composition - HAS-A relationship\n\n      add()\n        -> item as String\n        if item?\n          items += item\n\n      additionalMethod() as pure\n        <- rtn as Integer: length items\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"inheritance/inheritance_math_operations.ek9","url":"https://ek9.io/examples/inheritance/inheritance_math_operations.html","title":"Functions that are an abstract function","code":"#!ek9\ndefines module site.inheritance.mathoperations\n  defines function\n\n    mathOperation() as pure abstract\n      ->\n        x as Float\n        y as Float\n      <-\n        result as Float?\n\n    add() is mathOperation as pure\n      ->\n        x as Float\n        y as Float\n      <-\n        result as Float: x + y\n\n    subtract() is mathOperation as pure\n      ->\n        x as Float\n        y as Float\n      <-\n        result as Float: x - y\n\n    divide() is mathOperation as pure\n      ->\n        x as Float\n        y as Float\n      <-\n        result as Float: x / y\n\n    multiply() is mathOperation as pure\n      ->\n        x as Float\n        y as Float\n      <-\n        result as Float: x * y\n\n  defines program\n\n    MathExample()\n      stdout <- Stdout()\n      stdout.println(\"Math Operation Example\")\n\n      for op in [add, subtract, divide, multiply]\n        stdout.println(`Result: ${op(21, 7)}`)","expectedOutput":"Math Operation Example\nResult: 28.0\nResult: 14.0\nResult: 3.0\nResult: 147.0\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"inheritance/inheritance_open_animal.ek9","url":"https://ek9.io/examples/inheritance/inheritance_open_animal.html","title":"A class declared as open, and a subclass overriding its method","code":"#!ek9\ndefines module site.inheritance.openanimal\n\n  defines class\n\n    Animal as open  // Explicitly opened for extension\n      name as String: String()\n\n      speak()\n        Stdout().println(\"Generic animal sound\")\n\n      default operator ?\n\n    Dog extends Animal  // Now works - Animal is open\n      override speak()\n        Stdout().println(\"Woof!\")\n\n  defines program\n\n    AnimalSounds()\n      for animal in [Animal(), Dog()]\n        animal.speak()","expectedOutput":"Generic animal sound\nWoof!\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"inheritance/inheritance_speakable.ek9","url":"https://ek9.io/examples/inheritance/inheritance_speakable.html","title":"Polymorphism through a trait","code":"#!ek9\ndefines module site.inheritance.speakable\n\n  defines trait\n\n    Speakable  // Open for implementation - no \"as open\" needed\n      speak()\n\n  defines class\n\n    Dog with trait of Speakable  // Implements trait\n      name as String: String()\n\n      override speak()\n        Stdout().println(\"Woof!\")\n\n      default operator ?\n\n    Cat with trait of Speakable  // Implements trait\n      name as String: String()\n\n      override speak()\n        Stdout().println(\"Meow!\")\n\n      default operator ?\n\n  defines function\n\n    makeSpeak()\n      -> animal as Speakable  // Polymorphism via trait\n      animal.speak()\n\n  defines program\n\n    MakeThemSpeak()\n      makeSpeak(Dog())\n      makeSpeak(Cat())","expectedOutput":"Woof!\nMeow!\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"inheritance/inheritance_userlist.ek9","url":"https://ek9.io/examples/inheritance/inheritance_userlist.html","title":"A UserList that HAS-A List","code":"#!ek9\ndefines module site.inheritance.userlist\n\n  defines class\n\n    User\n      name as String: String()\n\n      User()\n        -> name as String\n        this.name: name\n\n      default User()\n\n      isValid() as pure\n        <- rtn as Boolean: name?\n\n      default operator ?\n\n    UserList\n      users as List of User: List()  // HAS-A relationship\n\n      addIfValid()\n        -> user as User\n        if user.isValid()\n          users += user\n      // Clear separation: UserList uses List\n      // Not confused with List itself\n      // Can change storage (Set? Array?) easily\n\n      size() as pure\n        <- rtn as Integer: length users\n\n      default operator ?\n\n  defines program\n\n    ValidUsers()\n      validUsers <- UserList()\n      validUsers.addIfValid(User(\"Steve\"))\n      validUsers.addIfValid(User())\n      Stdout().println(`Valid users: ${validUsers.size()}`)","expectedOutput":"Valid users: 1\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"introduction/introduction_addresses.ek9","url":"https://ek9.io/examples/introduction/introduction_addresses.html","title":"A web service with one GET operation","code":"#!ek9\ndefines module site.introduction.addresses\n\n  defines service\n\n    //define the service called 'Addresses', map it to a URI of '/addresses' and open it to callers\n    Addresses for :/addresses open\n\n      //A GET\n      listByPostCode() as GET for :/{postCode}\n        ->\n          postCode as String :=: PATH \"postCode\"\n          acceptLanguage as String :=: HEADER \"Accept-Language\"\n        <-\n          response as HTTPResponse: (postCode, acceptLanguage) with trait of HTTPResponse\n            //override HTTPResponse content, status and so on to complete processing.\n            override content()\n              <- rtn as Bytes: Bytes().withUtf8(`{\"postCode\": \"${postCode}\"}`)\n            override contentType() as pure\n              <- rtn as String: \"application/json\"\n            override contentLanguage() as pure\n              <- rtn as String: acceptLanguage\n            override status() as pure\n              <- rtn as Integer: 200\n            default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"introduction/introduction_hello.ek9","url":"https://ek9.io/examples/introduction/introduction_hello.html","title":"Hello, World","code":"#!ek9\ndefines module site.introduction.hello\n  defines program\n\n    HelloWorld()\n      stdout <- Stdout()\n      stdout.println(\"Hello, World\")","expectedOutput":"Hello, World\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"introduction/introduction_pipeline.ek9","url":"https://ek9.io/examples/introduction/introduction_pipeline.html","title":"A readable stream pipeline over people","code":"#!ek9\ndefines module site.introduction.pipeline\n\n  defines record\n\n    Person\n      first as String: String()\n      last as String: String()\n      dob as Date: Date()\n      profession as String: String()\n\n      default Person() as pure\n\n      Person() as pure\n        ->\n          first as String\n          last as String\n          dob as Date\n          profession as String\n        this.first :=? first\n        this.last :=? last\n        this.dob :=? dob\n        this.profession :=? profession\n\n      default operator ?\n\n      operator $ as pure\n        <- rtn as String: `${first} ${last}`\n\n  defines function\n\n    lastNameAndDob() as pure\n      -> p as Person\n      <- rtn as String: `${p.last} ${p.dob}`\n\n    lastNameComparison() as pure\n      ->\n        p1 as Person\n        p2 as Person\n      <- rtn as Integer: p1.last <=> p2.last\n\n    personProfession() as pure\n      -> p as Person\n      <- rtn as String: p.profession\n\n    professionComparison() as pure\n      ->\n        group1 as List of Person\n        group2 as List of Person\n      <- rtn as Integer: group1.getOrDefault(0, Person()).profession <=> group2.getOrDefault(0, Person()).profession\n\n    personToString() as pure\n      -> group as List of Person\n      <- rtn as String: $ group\n\n  defines program\n\n    Preview()\n      stdout <- Stdout()\n\n      people <- [\n        Person(first: \"Jane\", last: \"Doe\", dob: 1980-03-04, profession: \"Doctor\"),\n        Person(first: \"John\", last: \"Smith\", dob: 1960-01-01, profession: \"IT\"),\n        Person(first: \"Anne\", last: \"Jones\", dob: 1972-05-06, profession: \"Engineer\"),\n        Person(first: \"John\", last: \"Smith\", dob: 1960-01-01, profession: \"IT\"),\n        Person(first: \"Bill\", last: \"Adams\", dob: 1990-07-08, profession: \"Doctor\")\n        ]\n\n      cat people | uniq by lastNameAndDob | sort with lastNameComparison | group by personProfession | sort by professionComparison | map with personToString > stdout\n\n      cat people\n        | uniq by lastNameAndDob\n        | sort with lastNameComparison\n        | group by personProfession\n        | sort by professionComparison\n        | map with personToString\n        > stdout","expectedOutput":"[Bill Adams, Jane Doe]\n[Anne Jones]\n[John Smith]\n[Bill Adams, Jane Doe]\n[Anne Jones]\n[John Smith]\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"methods/methods_sanitized.ek9","url":"https://ek9.io/examples/methods/methods_sanitized.html","title":"A method taking a sanitized parameter","code":"#!ek9\ndefines module site.methods.sanitized\n\n  defines class\n\n    UserService\n      biographies as Dict of (Integer, String): Dict()\n\n      updateProfile()\n        ->\n          userId as Integer\n          biography as sanitized String\n        <- success as Boolean: false\n        //The biography is sanitized before this method receives it\n        biographies += DictEntry(userId, biography)\n        success: true\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"networkTypes/networkTypes_tcp_client.ek9","url":"https://ek9.io/examples/networkTypes/networkTypes_tcp_client.html","title":"A TCP client sending one message","code":"#!ek9\ndefines module site.networkTypes.tcpClient\n  defines program\n    TCPClient1()\n      stdout <- Stdout()\n      stderr <- Stderr()\n      localhost <- Networking().loopbackV4()\n\n      try\n        -> tcpClient <- TCP(NetworkProperties(localhost, 4446))\n\n        if tcpClient?\n          stdout.println(`Will attempt to connect to server ${tcpClient}`)\n          try\n            -> connection <- tcpClient.connect()\n            if connection?\n              connection.output().println(\"Short Message\")\n              stdout.println(`Received response [${connection.input().next()}]`)\n              //End of the try will just close the connection.\n            else\n              stderr.println(`Failed to connect [${tcpClient}]`)\n        else\n          stderr.println(`Failed to get TCP client running [${tcpClient}]`)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"networkTypes/networkTypes_tcp_client_stream.ek9","url":"https://ek9.io/examples/networkTypes/networkTypes_tcp_client_stream.html","title":"A TCP client streaming messages, then shutting the server down","code":"#!ek9\ndefines module site.networkTypes.tcpClientStream\n\n  defines function\n    shutdownFunction()\n      -> tcpClient as TCP\n      <- response as String: `Connection failed ${tcpClient}`\n\n      if tcpClient?\n        try\n          -> connection <- tcpClient.connect()\n          if connection?\n            connection.output().println(\"SHUTDOWN\")\n            response: `Received response [${connection.input().next()} from ${tcpClient}]`\n          else\n            response: `Failed to connect on [${tcpClient}]`\n      else\n        response: `Failed to get TCP client running [${tcpClient}]`\n\n    processingFunction() as abstract\n      -> input as String\n      <- response as String?\n\n  defines program\n    TCPClient2()\n      ->\n        processingPort as Integer\n        controlPort as Integer\n\n      stdout <- Stdout()\n      localhost <- Networking().loopbackV4()\n      try\n        -> processingClient <- TCP(NetworkProperties(localhost, processingPort))\n\n        if processingClient?\n          try\n            -> connection <- processingClient.connect()\n            sender <- (connection) is processingFunction as function\n              connection.output().println(input)\n              response: connection.input().next()\n\n            cat [\"one\", \"two\", \"Alpha\", \"Beta\", \"Zeta\", \"end\", \"begin\"] | map with sender > stdout\n\n      //The control client is closeable, so it is acquired in a try and lent to the function.\n      try\n        -> controlClient <- TCP(NetworkProperties(localhost, controlPort))\n        stdout.println(shutdownFunction(controlClient))","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"networkTypes/networkTypes_tcp_ready.ek9","url":"https://ek9.io/examples/networkTypes/networkTypes_tcp_ready.html","title":"A TCP server and its client in one program","code":"#!ek9\ndefines module site.networkTypes.tcpReady\n\n  defines function\n\n    echo() is TCPHandler\n      ->\n        input as StringInput\n        output as StringOutput\n      while input?\n        output.println(`echo:${input.next()}`)\n\n  defines program\n\n    TCPServerAndItsClient()\n      stdout <- Stdout()\n      props <- NetworkProperties(port: 0, backlog: 2, maxConcurrent: 2, localOnly: true)\n\n      try\n        -> tcpServer <- TCP(props)\n        client <- (stdout, props) is TCPReadyHandler as function\n          loopback <- Networking().loopbackV4()\n          try\n            -> connection <- TCP(NetworkProperties(loopback, props.port)).connect()\n            if connection?\n              connection.output().println(\"hello\")\n              stdout.println(`Received [${connection.input().next()}]`)\n          server.stop()\n\n        if tcpServer.acceptUntilComplete(echo, client)\n          stdout.println(`Served until the client completed, server still set ${tcpServer?}`)\n      stdout.println(\"The try has closed the server\")","expectedOutput":"Received [echo:hello]\nServed until the client completed, server still set true\nThe try has closed the server\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"networkTypes/networkTypes_tcp_server.ek9","url":"https://ek9.io/examples/networkTypes/networkTypes_tcp_server.html","title":"A TCP server handling connections","code":"#!ek9\ndefines module site.networkTypes.tcpServer\n  defines program\n    TCPServer1()\n      stdout <- Stdout()\n      stderr <- Stderr()\n\n      stdout.println(`Version of program package is ${Package().version}`)\n\n      try\n        -> tcpServer <- TCP(NetworkProperties(port: 4446, backlog: 5, maxConcurrent: 4, localOnly: true))\n\n        if tcpServer?\n          handler <- (tcpServer, stderr) extends TCPHandler as function\n            stderr.println(\"Connection made\")\n            while input?\n              line <- input.next()\n              stderr.println(`Received [${line}]`)\n              output.println(line.trim().upperCase())\n              if line == \"shutdown\"\n                tcpServer.stop()\n            stderr.println(\"No more input on connection\")\n\n          stdout.println(\"Awaiting connections\")\n          if tcpServer.accept(handler)\n            stdout.println(\"TCP Server completed and shutdown\")\n          else\n            stderr.println(`Was not able to service requests gracefully [${tcpServer}]`)\n        else\n          stderr.println(`Failed to get TCP server running [${tcpServer}]`)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"networkTypes/networkTypes_tcp_two_servers.ek9","url":"https://ek9.io/examples/networkTypes/networkTypes_tcp_two_servers.html","title":"Two TCP servers run concurrently, one controlling the other","code":"#!ek9\ndefines module site.networkTypes.tcpTwoServers\n\n  defines function\n    serverFunction() as abstract\n      <- response as String?\n\n    serviceConnections()\n      ->\n        tcpServer as TCP\n        handler as TCPHandler\n      <-\n        response as String: `TCP Server on ${tcpServer} completed and shutdown`\n\n      if not tcpServer.accept(handler)\n        response: `Was not able to service requests gracefully on ${tcpServer}`\n\n    createShutdownHandler\n      ->\n        controlServer as TCP\n        processingServer as TCP\n        shutdownCommand as String\n      <-\n        rtn as TCPHandler: (controlServer, processingServer, shutdownCommand) is TCPHandler as function\n          while input?\n            command <- input.next()\n            if command == shutdownCommand\n              output.println(\"Shutting down\")\n              processingServer.stop()\n              controlServer.stop()\n            else\n              output.println(`Ignoring [${command}]`)\n\n    createHandler()\n      <- rtn as TCPHandler: () is TCPHandler as function\n          cat input | map toUpperCase > output\n\n    toUpperCase()\n      -> input as String\n      <- output as String: input.upperCase()\n\n    shutdownFunction()\n      -> tcpClient as TCP\n      <- response as String: `Connection failed ${tcpClient}`\n\n      if tcpClient?\n        try\n          -> connection <- tcpClient.connect()\n          if connection?\n            connection.output().println(\"SHUTDOWN\")\n            response: `Received response [${connection.input().next()} from ${tcpClient}]`\n          else\n            response: `Failed to connect on [${tcpClient}]`\n      else\n        response: `Failed to get TCP client running [${tcpClient}]`\n\n  defines program\n    TCPServer2()\n      ->\n        processingPort as Integer\n        controlPort as Integer\n        shutdownCommand as String\n\n      stdout <- Stdout()\n\n      //Alternative layout as there are a number of properties being set.\n      //Both servers are named, so both are try-with-resources resources, closed when the try ends.\n      try\n        ->\n          processingServer <- TCP(\n            NetworkProperties(\n              port: processingPort,\n              timeout: 250ms,\n              backlog: 2,\n              maxConcurrent: 4,\n              localOnly: false)\n            )\n          controlServer <- TCP(NetworkProperties(port: controlPort, localOnly: true))\n\n        if controlServer? and processingServer?\n\n          shutdownControl <- (controlServer, processingServer, shutdownCommand) extends serverFunction\n            response: serviceConnections(\n              tcpServer: controlServer,\n              handler: createShutdownHandler(controlServer, processingServer, shutdownCommand)\n            )\n\n          processing <- (processingServer) is serverFunction\n            response: serviceConnections(\n              tcpServer: processingServer,\n              handler: createHandler()\n            )\n\n          //Now run both of those serverFunctions concurrently.\n          cat [shutdownControl, processing] | async > stdout\n          //Once the serverFunctions both finish this program will finally exit.\n        else\n          Stderr().println(`Failed to start servers, control: ${controlServer} processing: ${processingServer}`)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"networkTypes/networkTypes_udp_client.ek9","url":"https://ek9.io/examples/networkTypes/networkTypes_udp_client.html","title":"A UDP client sending two packets","code":"#!ek9\ndefines module site.networkTypes.udpClient\n  defines program\n    UDPClient1()\n      stdout <- Stdout()\n      stderr <- Stderr()\n      localhost <- Networking().loopbackV4()\n\n      try //use a try block with a closable resource, auto close\n        -> client <- UDP(NetworkProperties(timeout: 250ms))\n\n        packet1 <- UDPPacket(NetworkProperties(localhost, 4445), \"A Test\")\n        stdout.println(`Sending [${packet1}]`)\n        client.send(packet1)\n        stdout.println(\"Waiting for response\")\n        response1 <- client.receive()\n        if response1?\n          stdout.println(`Received [${response1}]`)\n        else\n          stderr.println(`There was no response [${client.lastErrorMessage()}]`)\n\n        packet2 <- UDPPacket(NetworkProperties(host: localhost, port: 4445), \"end\")\n        stdout.println(`Sending [${packet2}]`)\n        client.send(packet2)\n        stdout.println(\"Waiting for response\")\n        response2 <- client.receive()\n        if response2?\n          stdout.println(`Received [${response2}]`)\n        else\n          stderr.println(`There was no response [${client.lastErrorMessage()}]`)\n\n      stdout.println(\"UDP Client Complete\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"networkTypes/networkTypes_udp_client_stream.ek9","url":"https://ek9.io/examples/networkTypes/networkTypes_udp_client_stream.html","title":"A UDP client streaming packets","code":"#!ek9\ndefines module site.networkTypes.udpClientStream\n  defines type\n    List of String\n\n  defines function\n    packetConverter() as abstract\n      -> content as String\n      <- outgoing as UDPPacket?\n\n  defines program\n    UDPClient2()\n      ->\n        port as Integer\n        timeout as Millisecond\n      host <- Networking().loopbackV4()\n      try\n        -> udpConnection <- UDP(NetworkProperties(timeout))\n\n        //This is the nearest we get to a lambda, inline dynamic function\n        //You must use () for the single line you are allowed.\n        cat [\"A Test\", \"Middle Item\", \"end\" ]\n          | map (host, port) extends packetConverter (outgoing: UDPPacket(NetworkProperties(host, port), content))\n          > udpConnection\n\n      Stdout().println(\"UDP Client Complete\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"networkTypes/networkTypes_udp_server.ek9","url":"https://ek9.io/examples/networkTypes/networkTypes_udp_server.html","title":"A UDP echo server that stops on a message","code":"#!ek9\ndefines module site.networkTypes.udpServer\n  defines program\n    UDPServer1()\n      stdout <- Stdout()\n      try\n        -> udpConnection <- UDP(NetworkProperties(port: 4445))\n\n        //The loop stops on a condition; the try closes the connection when it ends.\n        serving <- true\n        while serving and udpConnection?\n          packet <- udpConnection.receive()\n          if packet?\n            if packet.content == \"end\"\n              endPacket <- UDPPacket(packet.properties, \"OK will stop Server\")\n              udpConnection.send(endPacket)\n              serving: false\n            else\n              udpConnection.send(packet)\n\n      stdout.println(\"UDP Server Complete\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"networkTypes/networkTypes_udp_server_iterator.ek9","url":"https://ek9.io/examples/networkTypes/networkTypes_udp_server_iterator.html","title":"A UDP echo server using the iterator syntax","code":"#!ek9\ndefines module site.networkTypes.udpServerIterator\n  defines program\n    UDPServerIterator()\n      stdout <- Stdout()\n      try\n        -> udpConnection <- UDP(NetworkProperties(port: 4445))\n\n        //The loop stops on a condition; the try closes the connection when it ends.\n        serving <- true\n        while serving and udpConnection.hasNext()\n          packet <- udpConnection.next()\n          if packet?\n            if packet.content == \"end\"\n              endPacket <- UDPPacket(packet.properties, \"OK will stop Server\")\n              udpConnection.send(endPacket)\n              serving: false\n            else\n              udpConnection.send(packet)\n\n      stdout.println(\"UDP Server Complete\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"networkTypes/networkTypes_udp_server_signals.ek9","url":"https://ek9.io/examples/networkTypes/networkTypes_udp_server_signals.html","title":"A UDP echo server stopped by a signal","code":"#!ek9\ndefines module site.networkTypes.udpServerSignals\n  defines function\n    UDPPacketHandler() as abstract\n      -> incoming as UDPPacket\n      <- outgoing as UDPPacket?\n\n  defines program\n    UDPServer2()\n      ->\n        port as Integer\n        packetSize as Integer\n        signal as String\n\n      stdout <- Stdout()\n      try\n        -> udpConnection <- UDP(NetworkProperties(port, packetSize))\n\n        //This time stop server with abort signal not content 'end'.\n        //A handler that returns a set Integer ends the process with that exit code.\n        //It does not close the connection it could capture - only the try that owns it does.\n        abortHandler <- () is SignalHandler as function\n          result: 0\n          stderr <- Stderr()\n          stderr.println(\"Received abort Signal stopping server\")\n\n        Signals().register(signal, abortHandler)\n\n        echoFunction <- (udpConnection) is UDPPacketHandler\n          outgoing = incoming\n          udpConnection.send(outgoing)\n\n        cat udpConnection | map by echoFunction > stdout\n      stdout.println(\"UDP Server Complete\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"operators/operators_assign_if_unset.ek9","url":"https://ek9.io/examples/operators/operators_assign_if_unset.html","title":"Assign if unset","code":"#!ek9\ndefines module site.operators.assignifunset\n\n  defines function\n\n    chooseBirds()\n      -> initialBird as String\n      stdout <- Stdout()\n\n      //Setup values\n      bird1 as String: String()\n\n      bird1 :=? \"Goose\"\n      //bird1 would have the value of \"Goose\" because 'bird1' is not set\n\n      //In contrast.\n      bird2 <- initialBird //initialBird has the value \"Duck\"\n\n      bird2 :=? \"Goose\"\n      //bird2 would have the value of \"Duck\" because 'bird2' was originally set\n\n      stdout.println(`${bird1} ${bird2}`)\n\n  defines program\n\n    AssignIfUnset()\n      chooseBirds(\"Duck\")","expectedOutput":"Goose Duck\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"operators/operators_assignment.ek9","url":"https://ek9.io/examples/operators/operators_assignment.html","title":"Assignment shares a reference, it does not copy","code":"#!ek9\ndefines module site.operators.assignment\n\n  defines record\n\n    Address\n      country as String: String()\n\n      default Address()\n\n      Address()\n        -> country as String\n        this.country: country\n\n      default operator ?\n\n  defines program\n\n    Assignment()\n      stdout <- Stdout()\n\n      checkAddr <- Address() //a new empty address, so it is unset\n      myAddress <- Address() //assigned to a new empty address\n\n      myAddress.country: \"UK\" //assuming the Address was a record with a country field\n\n      checkAddr := myAddress\n      //Both myAddress and checkAddr reference the same address\n      //But the data has not been copied\n\n      //Change the country in either checkAddr or myAddress and value will alter\n      checkAddr.country = \"US\"\n      //myAddress.country is now also \"US\"\n\n      anAddress <- Address() //a new empty address, so it is unset\n\n      anAddress :=? myAddress\n      //anAddress is only assigned if it was unset or had no memory allocated; as above.\n\n      anAddress :=? Address(\"US\")\n      //anAddress would not have been assign above as it already has a valid Address value\n\n      stdout.println(myAddress.country)\n      stdout.println(anAddress.country)","expectedOutput":"US\nUS\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"operators/operators_basics.ek9","url":"https://ek9.io/examples/operators/operators_basics.html","title":"Operators on values, lists, strings and ranges","code":"#!ek9\ndefines module site.operators.basics\n\n  defines function\n\n    addition()\n      stdout <- Stdout()\n\n      result <- 6 + 8\n\n      stdout.println(result)\n\n    listAddition()\n      stdout <- Stdout()\n\n      //Simple list of string values (note this is shorthand for a List and is not an array)\n      aList <- [ \"A\", \"B\", \"C\" ]\n      //aList remains unmodified as does \"D\"\n      list2 <- aList + \"D\"\n      //Now modify list2 - but note the different operator\n      list2 += \"E\"\n\n      //Create another list to be used.\n      endList <- [ \"X\", \"Y\", \"Z\" ]\n      //Same syntax and semantics, but different parameters\n      finalList <- list2 + endList\n      //But the result finalList is obvious as [\"A\", \"B\", \"C\", \"D\", \"E\", \"X\", \"Y\", \"Z\"]\n\n      stdout.println(aList)\n      stdout.println(finalList)\n\n    comparisons()\n      stdout <- Stdout()\n\n      one <- 1\n      two <- 2\n      three <- 3\n      alsoThree <- 3\n      six <- 6\n      eight <- 8\n      lessThan <- one < two //results in true\n      greaterThan <- one > two //results in false\n      greaterOrEqual <- three >= two //results in true\n      lessOrEqual <- three <= two //results in false\n      notEqual <- three <> alsoThree //results in false\n      alsoNotEqual <- three != alsoThree //results in false\n      equal <- three == alsoThree //results in true\n      inRange <- three in two ... eight //results in true\n      notInRange <- six not in two ... eight //results in false\n\n      stdout.println(`${lessThan} ${greaterThan} ${greaterOrEqual} ${lessOrEqual} ${notEqual}`)\n      stdout.println(`${alsoNotEqual} ${equal} ${inRange} ${notInRange}`)\n\n    stringOperators()\n      stdout <- Stdout()\n\n      steve <- \"Steve\"\n      capitalTe <- \"Te\"\n      lowerTe <- \"te\"\n      stevenPattern <- /[S|s]te(?:ven?|phen)/\n      noMatch <- steve contains capitalTe //results in false\n      hasMatch <- steve contains lowerTe //results in true\n      matchesLeft <- steve matches stevenPattern //results in true\n      matchesRight <- stevenPattern matches steve //also results in true\n\n      stdout.println(`${noMatch} ${hasMatch} ${matchesLeft} ${matchesRight}`)\n\n  defines program\n\n    Basics()\n      addition()\n      listAddition()\n      comparisons()\n      stringOperators()","expectedOutput":"14\n[\"A\", \"B\", \"C\"]\n[\"A\", \"B\", \"C\", \"D\", \"E\", \"X\", \"Y\", \"Z\"]\ntrue false true false false\nfalse true true false\nfalse true true true\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"operators/operators_coalescing.ek9","url":"https://ek9.io/examples/operators/operators_coalescing.html","title":"Coalescing operators","code":"#!ek9\ndefines module site.operators.coalescing\n\n  defines program\n\n    Coalescing()\n      stdout <- Stdout()\n\n      //Initialise values\n      bird1 as String: String()\n      bird2 <- \"Duck\"\n      answerA <- bird1 <? bird2\n      answerA := bird1 <=? bird2\n      answerA := bird1 >? bird2\n      answerA := bird1 >=? bird2\n      //In all above examples answerA would have the value of \"Duck\" because 'bird1' is not set\n\n      //As you can see bird1 is not less than, equal to or greater than bird2 because bird1 not set.\n\n      answerB <- bird1 ?: bird2\n      //answerB would also have the value of \"Duck\" because 'bird1' is not set\n\n      answerA := bird1 ?? bird2\n      //answerA would now be un set and not have a meaningful value because it has taken same value as 'bird1'\n      //But importantly bird1 does have memory allocated.\n\n      answerB := bird1 ?: bird2\n      //answerB would have the value of \"Duck\" because 'bird1' does not have a meaningful value but does have memory allocated.\n      //this is the main difference between ?? and ?:\n      //By the same logic answerB would have the value of \"Duck\" when the <?, <=?, >?, >=? operators are used.\n\n      bird1 := \"Goose\"\n      answerC <- bird1 ?? bird2\n      //answerC would now have the value of \"Goose\" because bird1 is set\n      answerC := bird1 ?: bird2\n      //answerC would also have the value of \"Goose\" because bird1 is set\n      answerC := bird1 <? bird2\n      //answerC would have the value of \"Duck\"\n      answerC := bird1 <=? bird2\n      //answerC would have the value of \"Duck\"\n      answerC := bird1 >? bird2\n      //answerC would have the value of \"Goose\"\n      answerC := bird1 >=? bird2\n      //answerC would have the value of \"Goose\"\n\n      stdout.println(`${answerA?} ${answerB} ${answerC}`)","expectedOutput":"false Duck Goose\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"operators/operators_coalescing_benefit.ek9","url":"https://ek9.io/examples/operators/operators_coalescing_benefit.html","title":"Why the coalescing comparison operators exist","code":"#!ek9\ndefines module site.operators.coalescingbenefit\n\n  defines function\n\n    functionToGetBird1() as pure\n      <- rtn as String: String()\n\n    functionToGetBird2() as pure\n      <- rtn as String: \"Duck\"\n\n  defines program\n\n    CoalescingBenefit()\n      stdout <- Stdout()\n\n      //Values to work with\n      bird1 <- functionToGetBird1()\n      bird2 <- functionToGetBird2()\n\n      //Without using new operators\n      answerA <- String()\n      if not bird1?\n        answerA := bird2\n      else if not bird2?\n        answerA := bird1\n      else\n        answerA := bird1 < bird2 <- bird1 else bird2\n\n      //With the new operator\n      answerA := bird1 <? bird2\n\n      //With the new operator and function calls\n      answerA := functionToGetBird1() <? functionToGetBird2()\n      //Without the new operators, you would want to avoid multiple calls!\n\n      stdout.println(answerA)","expectedOutput":"Duck\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"operators/operators_compare_different.ek9","url":"https://ek9.io/examples/operators/operators_compare_different.html","title":"Comparing different strings","code":"#!ek9\ndefines module site.operators.comparedifferent\n\n  defines program\n\n    CompareDifferent()\n      stdout <- Stdout()\n\n      steve <- \"Steve\"\n      lowerCase <- \"steve\"\n      longer <- \"Steven\"\n      suffix <- \"teve\"\n      lowerLonger <- \"steven\"\n      caseCompare <- steve <=> lowerCase //results in -32\n      fuzzyOne <- steve <~> longer //results in 2\n      fuzzyTwo <- steve <~> suffix //results in 1\n      fuzzyThree <- steve <~> lowerLonger //results in 3\n\n      stdout.println(`${caseCompare} ${fuzzyOne} ${fuzzyTwo} ${fuzzyThree}`)","expectedOutput":"-32 2 1 3\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"operators/operators_compare_same.ek9","url":"https://ek9.io/examples/operators/operators_compare_same.html","title":"Comparing equal strings","code":"#!ek9\ndefines module site.operators.comparesame\n\n  defines program\n\n    CompareSame()\n      stdout <- Stdout()\n\n      steve <- \"Steve\"\n      sameName <- \"Steve\"\n      sameCompare <- steve <=> sameName //results in 0\n      sameFuzzy <- steve <~> sameName //results in 0\n\n      stdout.println(`${sameCompare} ${sameFuzzy}`)","expectedOutput":"0 0\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"operators/operators_discarded.ek9","url":"https://ek9.io/examples/operators/operators_discarded.html","title":"Using the result of an operator","code":"#!ek9\ndefines module site.operators.discarded\n\n  defines program\n\n    Discarded()\n      stdout <- Stdout()\n\n      price <- 100\n      tax <- 20\n\n      //GOOD: Assign the result\n      total <- price + tax\n      //GOOD: Or use the mutating operator if mutation is the intent\n      price += tax\n\n      stdout.println(`${total} ${price}`)","expectedOutput":"120 120\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"operators/operators_discarded_bad.ek9","url":"https://ek9.io/examples/operators/operators_discarded_bad.html","title":"Discarding the result of an operator","code":"#!ek9\ndefines module bad.site.operators.discarded\n\n  defines function\n\n    discardedAddition()\n      price <- 100\n      tax <- 20\n\n      //BAD: Computation result goes nowhere - dead code (E11050)\n      price.+(tax)","expectedOutput":null,"kind":"bad","errors":["E11050"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"operators/operators_isset.ek9","url":"https://ek9.io/examples/operators/operators_isset.html","title":"The is-set operator on values and calculations","code":"#!ek9\ndefines module site.operators.isset\n\n  defines program\n\n    IsSet()\n      stdout <- Stdout()\n\n      name1 <- \"Bill\"\n      name2 <- \"Ted\"\n      name1Set <- name1? //results in true\n\n      name3 as String: String()\n      name3Set <- name3? //results in false\n\n      name4 <- String()\n      name4Set <- name4? //results in false\n\n      //Note the validity of the calculation is been checked here not the actual result.\n      //The use of the '( ... )' is important here. The ? applies to the result.\n\n      validCalculation <- (name1 < name2)?\n      //results in true - because the calculation was valid not because Bill is Less than Ted\n      invalidCalculation <- (name1 < name3)?\n      //results in false - because the calculation was invalid name is not set\n\n      stdout.println(`${name1Set} ${name3Set} ${name4Set}`)\n      stdout.println(`${validCalculation} ${invalidCalculation}`)","expectedOutput":"true false false\ntrue false\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"operators/operators_logic.ek9","url":"https://ek9.io/examples/operators/operators_logic.html","title":"Boolean and Bits logical operators","code":"#!ek9\ndefines module site.operators.logic\n\n  defines function\n\n    booleanOperators()\n      stdout <- Stdout()\n\n      //Simple boolean values\n      a <- true\n      b <- true\n      c <- false\n\n      //Each of the operators\n      //The and/not operator\n      andAB <- a and b //result would be true\n      andAC <- a and c //result would be false\n      andNotC <- a and not c //result would be true\n      andTildeC <- a and ~c //result would be true\n\n      //The or/not operator\n      orAB <- a or b //result would be true\n      orAC <- a or c //result would be true\n      notAOrC <- not a or c //result would be false\n      tildeAOrC <- ~a or c //result would be false\n\n      //The xor/not operator\n      xorAB <- a xor b //result would be false\n      xorANotB <- a xor not b //result would be true\n      xorAC <- a xor c //result would be true\n      notAXorC <- not a xor c //result would be false\n      tildeAXorC <- ~a xor c //result would be false\n\n      stdout.println(`${andAB} ${andAC} ${andNotC} ${andTildeC}`)\n      stdout.println(`${orAB} ${orAC} ${notAOrC} ${tildeAOrC}`)\n      stdout.println(`${xorAB} ${xorANotB} ${xorAC} ${notAXorC} ${tildeAXorC}`)\n\n    bitsOperators()\n      stdout <- Stdout()\n\n      //Simple bits values\n      a <- 0b010011\n      b <- 0b101010\n      c <- 0B01010011\n\n      //Each of the operators\n      //The not operator\n      notA <- not a //result would be 0b101100\n\n      //The and operator\n      andAB <- a and b //result would be 0b000010\n\n      //The or operator\n      orAB <- a or b //result would be 0b111011\n\n      //The xor operator\n      xorAB <- a xor b //result would be 0b111001\n\n      //The << operator\n      shiftedOne <- c << 1 //result would be 0b010100110\n      shiftedTwo <- c << 2 //result would be 0b0101001100\n\n      //The >> operator\n      shiftedRight <- c >> 2 //result would be 0b010100\n\n      stdout.println(`${notA} ${andAB} ${orAB} ${xorAB}`)\n      stdout.println(`${shiftedOne} ${shiftedTwo} ${shiftedRight}`)\n\n  defines program\n\n    Logic()\n      booleanOperators()\n      bitsOperators()","expectedOutput":"true false true true\ntrue true false false\nfalse true true false false\n101100 000010 111011 111001\n010100110 0101001100 010100\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"operators/operators_mathematical.ek9","url":"https://ek9.io/examples/operators/operators_mathematical.html","title":"Mathematical operators and unset values","code":"#!ek9\ndefines module site.operators.mathematical\n\n  defines program\n\n    Mathematical()\n      stdout <- Stdout()\n\n      //Initialise values\n      a <- 21.9\n      b <- 13.6\n      c <- Float()\n      d <- Float()\n\n      //Addition examples\n      e <- a + b\n      //'e' would have the value of 35.5\n      e := b + a\n      //'e' would again have the value of 35.5\n\n      //But in these following cases 'c' is not set and so the result is also not set\n      e := a + c\n      e := c + a\n\n      //Also in these following cases both 'c' and 'd' are not set and so the result not set\n      e := c + d\n      e := d + c\n\n      //Subtraction examples\n      e := a - b //'e' = 8.299999999999999\n      e := b - a //'e' = -8.299999999999999\n      e := a - c //'e' = not set\n      e := c - a //'e' = not set\n      e := c - d //'e' = not set\n      e := d - c //'e' = not set\n\n      //Multiplication examples\n      e := a * b //'e' = 297.84\n      e := b * a //'e' = 297.84\n      //all other combinations involving 'c' or 'd' result in 'e' being not set\n\n      //Division examples\n      e := a / b //'e' = 1.6102941176470587\n      e := b / a //'e' = 0.6210045662100457\n      //all other combinations involving 'c' or 'd' result in 'e' being not set\n\n      //Factorial examples\n      alpha <- 5\n      e := alpha! //'e' = 120.0\n\n      //Power examples\n      beta <- 5\n      e := beta ^ 2 //'e' = 25.0\n      e := beta ^ 3 //'e' = 125.0\n      e := beta ^ 4.8 //'e' = 2264.936448992798\n\n      //Modulus and remainder examples\n      charlie <- -21\n      f <- charlie mod 4 //'f' = 3 because -21 + 4 x 6 is 3\n      f := charlie rem 4 //'f' = -1 because -21 / 4 gives -5 with a remainder of -1\n      //For positive values the results are the same for modulus and remainder\n      delta <- 21\n      f := delta mod 4 //'f' = 1\n      f := delta rem 4 //'f' = 1\n\n      //Absolute - abs example\n      f := abs charlie //'f' = 21\n      f := abs delta //'f' = 21\n      echo <- -23.88\n      e := abs echo //'e' = 23.88\n\n      //Square root - sqrt example\n      e := sqrt delta //'e' = 4.58257569495584\n      e := sqrt abs echo //'e' = 4.886716689148247\n      //Note the combination of sqrt and abs.\n\n      e := sqrt echo //'e' = not set cannot sqrt a negative number\n      //EK9 does not have imaginary numbers so sqrt of a negative number is not valid\n\n      stdout.println(`${e?} ${f}`)","expectedOutput":"false 21\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"operators/operators_mutation.ek9","url":"https://ek9.io/examples/operators/operators_mutation.html","title":"Modification operators on a Float","code":"#!ek9\ndefines module site.operators.mutation\n\n  defines program\n\n    Mutation()\n      stdout <- Stdout()\n\n      aFloat <- 22.9 //Create a new floating point value\n      aFloat += 17.1 //Add the value into the variable aFloat\n      //aFloat would now have the value of 40.0\n\n      aFloat -= 7.5 //Subtract the value from the variable aFloat\n      //aFloat would now have the value of 32.5\n\n      aFloat *= 3 //Multiply aFloat by the value\n      //aFloat would now have the value of 97.5\n\n      aFloat /= 2.5 //Divide aFloat by the value\n      //aFloat would now have the value of 39.0\n\n      aFloat++ //Increment aFloat by 1.0\n      //aFloat would now have the value of 40.0\n\n      aFloat-- //Decrement aFloat by 1.0\n      //aFloat would now have the value of 39.0 again\n\n      bFloat <- Float() //Create a new floating point value but not yet set\n      bFloat := aFloat //Assign the variable and update\n      aFloat++ //Increment aFloat by 1.0, but note bFloat will also change\n\n      cFloat <- Float() //Create another new floating point value but not yet set\n      cFloat :=: aFloat //Copy the contents of the variable and update\n      aFloat++ //Increment aFloat by 1.0, but note cFloat will not change\n\n      stdout.println(`aFloat ${aFloat}, bFloat ${bFloat}, cFloat ${cFloat}`)","expectedOutput":"aFloat 41.0, bFloat 41.0, cFloat 40.0\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"operators/operators_prefix.ek9","url":"https://ek9.io/examples/operators/operators_prefix.html","title":"Prefix operators on lists, strings and money","code":"#!ek9\ndefines module site.operators.prefix\n\n  defines program\n\n    Prefix()\n      stdout <- Stdout()\n\n      //Initialise values\n      anInteger <- 106\n      aList <- [\"V1\", \"V2\", \"V3\"] //Remember this is a List not an Array\n      aString <- \"A-to-Z\"\n      money <- 350.50#USD\n\n      //Examples of use with a List of Strings\n      isEmpty <- aList is empty //isEmpty will have value of false, because the list is not empty\n      isNotEmpty <- aList is not empty //isNotEmpty will have value of true, because the list is not empty\n      //The above could have been written as\n      isNotEmpty := not aList empty //But this reads like Yoda might have said it.\n\n      //Length example\n      listLength <- length of aList //listLength will be 3\n      //The above could have been written as\n      listLength := length aList //The 'of' is just to add readability\n\n      //Convert List to a String and get its length\n      listAsString <- $ aList //listAsString will be [\"V1\", \"V2\", \"V3\"]\n      lengthOfListAsString <- $ length of $ aList\n      //lengthOfListAsString will be 18\n\n      //Accessing specific items in the List safely with getOrDefault\n      v1 <- aList.getOrDefault(0, \"\") //v1 will be \"V1\"\n      v3 <- aList.getOrDefault(2, \"\") //v3 will be \"V3\"\n\n      //Access by index with a safe default for out-of-range indices\n      maybeAString <- aList.getOrDefault(5, \"\") //maybeAString will be \"\" - the default, as there are only 3 items\n      //getOrDefault always returns a value: either the element at the index, or the provided default\n      //No exceptions, no unset results - safe by design\n\n      //But the pipeline processing is more powerful\n      v2 <- cat aList | skip 1 | head 1 | collect as String //v2 will be \"V2\"\n      //Pipeline processing is also safe by avoiding indexing\n      nonExistent <- cat aList | skip 4 | head 1 | collect as String\n      //nonExistent will be not set as there are only 3 Strings in the list\n\n      //Same syntax can be used with Strings (or your own records/classes if you provide operators)\n      isEmpty := aString is empty //isEmpty will have value of false, because the string has a value of \"A-to-Z\"\n      firstChar <- #< aString //firstChar will be 'A'\n      lastChar <- #> aString //lastChar will be 'Z'\n      //The important point here is the same syntax works with different types like String, Integer, Money\n      //Further example shown using Money\n      amount <- #< money //amount will be 350.5\n      currency <- #> money //currency will be USD\n\n      //The following examples outline hash code and promotion of type\n      aFloat <- #^ anInteger //aFloat will be 106.0 (i.e a floating point number)\n      //With your own records and classes you can provide your own promotions\n\n      hashCode <- #? anInteger //hashCode will be 106\n      hashCode := #? aFloat //hashCode will be 1079672832\n\n      stdout.println(`${isEmpty} ${isNotEmpty} ${listLength} ${listAsString} ${lengthOfListAsString}`)\n      stdout.println(`${v1} ${v3} ${maybeAString} ${v2} ${nonExistent?}`)\n      stdout.println(`${firstChar} ${lastChar} ${amount} ${currency} ${aFloat} ${hashCode}`)","expectedOutput":"false true 3 [\"V1\", \"V2\", \"V3\"] 18\nV1 V3  V2 false\nA Z 350.5 USD 106.0 1079672832\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"operators/operators_record_merge.ek9","url":"https://ek9.io/examples/operators/operators_record_merge.html","title":"A record with its own copy, merge, equality and String operators","code":"#!ek9\ndefines module site.operators.recordmerge\n\n  defines function\n\n    //Shows an unset value as '-' so a partly filled Person can still be printed.\n    shown() as pure\n      -> text as String\n      <- rtn as String: text? <- text else \"-\"\n\n  defines record\n\n    Person\n      first <- String()\n      last <- String()\n      dob <- Date()\n      profession <- String()\n\n      //is set - only when every field is set\n      override operator ? as pure\n        <- rtn as Boolean: first? and last? and dob? and profession?\n\n      //convert to string\n      operator $ as pure\n        <- rtn as String: `${shown(first)}, ${shown(last)}, ${shown($dob)}, ${shown(profession)}`\n\n      //equality - written by hand, so the hash code is too, over the same fields\n      operator == as pure\n        -> other as Person\n        <- rtn as Boolean: first == other.first and last == other.last and dob == other.dob and profession == other.profession\n\n      operator #? as pure\n        <- rtn as Integer: #? first + #? last + #? dob + #? profession\n\n      //Field-wise copy - calls :=: on each field, each copying at its own level.\n      //'default operator :=:' is a SHALLOW copy - each field refers to the same object as the source's.\n      //Write your own :=: like this when you need a deeper or selective copy.\n      operator :=:\n        -> other as Person\n\n        //No 'if other?' guard: a partly filled Person is not 'set', but its fields must still be copied.\n        first :=: other.first\n        last :=: other.last\n        dob :=: other.dob\n        profession :=: other.profession\n\n      //merge - fill only what is unset, each with its own copy\n      operator :~:\n        -> other as Person\n\n        //No 'if other?' guard here either: it would skip every partly filled Person.\n        if not first?\n          first :=: String(other.first)\n\n        //Could be written like this with assign-if-unset.\n        last :=? String(other.last)\n        dob :=? Date(other.dob)\n        profession :=? String(other.profession)\n\n  defines program\n\n    //quick program to show how operators on Person can be used.\n    PersonMerge()\n      stdout <- Stdout()\n\n      john <- Person()\n      john.first: \"John\"\n      john.profession: \"IT\"\n\n      smith <- Person()\n      smith.last: \"Smith\"\n      smith.dob: 1960-01-01\n\n      //So lets merge these into a new variable\n      merged <- Person()\n\n      merged :~: john\n      merged :~: smith\n\n      //Alter first name\n      john.first: \"Jon\"\n\n      //A copy of the merged record, then just show the values.\n      copied <- Person()\n      copied :=: merged\n\n      stdout.println(`[${john}] set: ${john?}`)\n      stdout.println(`[${smith}] set: ${smith?}`)\n      stdout.println(`[${merged}] set: ${merged?}`)\n      stdout.println(`copied == merged: ${copied == merged}`)","expectedOutput":"[Jon, -, -, IT] set: false\n[-, Smith, 1960-01-01, -] set: false\n[John, Smith, 1960-01-01, IT] set: true\ncopied == merged: true\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"operators/operators_ternary.ek9","url":"https://ek9.io/examples/operators/operators_ternary.html","title":"The ternary operator","code":"#!ek9\ndefines module site.operators.ternary\n\n  defines program\n\n    Ternary()\n      stdout <- Stdout()\n\n      //Setup values\n      bird1 as String: String()\n      bird2 <- \"Duck\"\n\n      answerA <- bird1? <- bird1 : bird2\n      //answerA would have the value of \"Duck\" because 'bird1' is not set\n      //Note this could have been written as\n      answerA := bird1? <- bird1 else bird2\n      //Maybe this is less terse but more readable and obvious.\n\n      bird1 := String()\n      answerA := bird1? <- bird1 : bird2\n      //answerA would still have the value of \"Duck\" because 'bird1' does not have a meaningful value\n\n      bird1 := \"Goose\"\n      answerB <- bird1? <- bird1 : bird2\n      //answerB would now have the value of \"Goose\" because bird1 is set\n\n      stdout.println(`${answerA} ${answerB}`)","expectedOutput":"Duck Goose\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"packaging/deps/packaging_deps.ek9","url":"https://ek9.io/examples/packaging/deps/packaging_deps.html","title":"Declaring dependencies (with their exact versions)","code":"#!ek9\ndefines module site.packaging.deps\n\n  defines package\n\n    description <- \"Example of different constants in different modules.\"\n\n    //No need for includeFiles for source code anymore.\n    applyStandardIncludes <- true\n\n    deps <- {\n      \"ekopen.network.support.utils\": \"1.6.1-9\",\n      \"ekopen.net.handy.tools\": \"3.2.1-0\"\n      }\n\n  defines function\n    describe() as pure\n      <- rtn as String: \"site.packaging.deps\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"packaging/excludes/packaging_excludes.ek9","url":"https://ek9.io/examples/packaging/excludes/packaging_excludes.html","title":"Excluding a transitive dependency","code":"#!ek9\ndefines module site.packaging.excludes\n\n  defines package\n\n    description <- \"Example of different constants in different modules.\"\n\n    //No need for includeFiles for source code anymore.\n    applyStandardIncludes <- true\n\n    deps <- {\n      \"ekopen.network.support.utils\": \"1.6.1-9\",\n      \"ekopen.net.handy.tools\": \"3.2.1-0\"\n      }\n\n    excludeDeps <- {\n      \"ekopen.some.bad.dependency.pack\": \"ekopen.org.supertools.util\"\n      }\n\n  defines function\n    describe() as pure\n      <- rtn as String: \"site.packaging.excludes\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"packaging/httpclient/packaging_httpclient.ek9","url":"https://ek9.io/examples/packaging/httpclient/packaging_httpclient.html","title":"A publishable package declaring the capabilities it uses","code":"#!ek9\ndefines module site.packaging.httpclient\n\n  defines package\n\n    publicAccess <- true\n    version <- 1.0.0-0\n    description <- \"HTTP client library\"\n    license <- \"MIT\"\n\n    capabilities <- [\n      \"org.ek9.lang::TCP\",\n      \"org.ek9.lang::HTTPRequest\",\n      \"org.ek9.lang::HTTPResponse\",\n      \"org.ek9.lang::EnvVars\"\n      ]\n\n    deps <- {\n      \"org.ek9.collections\": \"1.0.0-0\"\n      }\n\n  defines function\n    describe() as pure\n      <- rtn as String: \"site.packaging.httpclient\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"packaging/includes/packaging_includes.ek9","url":"https://ek9.io/examples/packaging/includes/packaging_includes.html","title":"A package that names the files to compile","code":"#!ek9\ndefines module site.packaging.includes\n\n  references\n    site.packaging.includes.maths::PI\n    site.packaging.includes.physics::SPEED_OF_LIGHT\n\n  defines package\n\n    description <- \"Example of different constants in different modules.\"\n\n    //We only want this file and these two to be compiled.\n    includeFiles <- [\n      \"packaging_includes_maths.ek9\",\n      \"packaging_includes_physics.ek9\"\n      ]\n\n  defines program\n    ShowConstants()\n      stdout <- Stdout()\n      stdout.println(`Pi is ${PI} and the speed of light is ${SPEED_OF_LIGHT}`)","expectedOutput":"Pi is 3.14159 and the speed of light is 299792458\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"packaging/includes/packaging_includes_maths.ek9","url":"https://ek9.io/examples/packaging/includes/packaging_includes_maths.html","title":"An included file: a constant in its own module","code":"#!ek9\ndefines module site.packaging.includes.maths\n\n  defines constant\n    PI <- 3.14159","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"packaging/includes/packaging_includes_physics.ek9","url":"https://ek9.io/examples/packaging/includes/packaging_includes_physics.html","title":"Another included file: a constant in another module","code":"#!ek9\ndefines module site.packaging.includes.physics\n\n  defines constant\n    SPEED_OF_LIGHT <- 299792458","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"packaging/jsonparser/packaging_jsonparser.ek9","url":"https://ek9.io/examples/packaging/jsonparser/packaging_jsonparser.html","title":"A pure-computation package: no capabilities block","code":"#!ek9\ndefines module site.packaging.jsonparser\n\n  defines package\n\n    publicAccess <- true\n    version <- 2.1.0-0\n    description <- \"Pure JSON parsing library\"\n    license <- \"MIT\"\n\n    //No 'capabilities' block: pure computation, no gated types used.\n    //Omitting the block is the current idiom for pure libraries.\n\n    deps <- {\n      \"org.ek9.collections\": \"1.0.0-0\"\n      }\n\n  defines function\n    describe() as pure\n      <- rtn as String: \"site.packaging.jsonparser\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"packaging/nopackage/packaging_nopackage_hello.ek9","url":"https://ek9.io/examples/packaging/nopackage/packaging_nopackage_hello.html","title":"The program, now using the shared code - but with no package block","code":"#!ek9\ndefines module site.packaging.nopackage\n\n  defines program\n    HelloWorld()\n      stdout <- Stdout()\n      record <- BaseRecord()\n      duck <- Duck()\n      stdout.println(`Hello, World ${record.anything} ${duck.quack()}`)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"packaging/nopackage/packaging_nopackage_traits.ek9","url":"https://ek9.io/examples/packaging/nopackage/packaging_nopackage_traits.html","title":"Tier two begins: shared code in a second file of the same module","code":"#!ek9\ndefines module site.packaging.nopackage\n\n  defines record\n    BaseRecord as open\n      anything as Integer: 90\n\n      default operator ?\n\n  defines trait\n    Quack\n      quack() as pure\n        <- rtn as String?\n\n  defines class\n    Duck with trait of Quack\n      override quack() as pure\n        <- rtn as String: \"Quack\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"packaging/publish/packaging_publish.ek9","url":"https://ek9.io/examples/packaging/publish/packaging_publish.html","title":"A package ready to publish","code":"#!ek9\ndefines module site.packaging.publish\n\n  defines package\n\n    publicAccess <- true\n\n    version <- 2.3.14-0\n\n    description <- \"Example of different constants in different modules.\"\n\n    tags <- [\n      \"mathematics\",\n      \"constants\"\n      ]\n\n    license <- \"MIT\"\n\n    //Pure computation - no system resources used. No 'capabilities' block is\n    //declared, so capability enforcement is not activated for this package.\n    //See the Capability Security section below for details.\n\n    applyStandardIncludes <- true\n\n    includeFiles <- [\n      \"License.txt\",\n      \"Copyright.txt\",\n      \"Authors.txt\"\n      ]\n\n    //certain files like .gitignore we don't want to package\n    applyStandardExcludes <- true\n\n    deps <- {\n      \"ekopen.network.support.utils\": \"1.6.1-9\",\n      \"ekopen.net.handy.tools\": \"3.2.1-0\"\n      }\n\n    excludeDeps <- {\n      \"ekopen.some.bad.dependency.pack\": \"ekopen.org.supertools.util\"\n      }\n\n  defines function\n    describe() as pure\n      <- rtn as String: \"site.packaging.publish\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"packaging/single/packaging_single.ek9","url":"https://ek9.io/examples/packaging/single/packaging_single.html","title":"Tier one: a single file, a single module, one program","code":"#!ek9\ndefines module site.packaging.single\n\n  defines program\n    HelloWorld()\n      stdout <- Stdout()\n      stdout.println(\"Hello, World\")","expectedOutput":"Hello, World\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"packaging/twomodules/packaging_twomodules_hello.ek9","url":"https://ek9.io/examples/packaging/twomodules/packaging_twomodules_hello.html","title":"The program's module references the class it uses from the new one","code":"#!ek9\ndefines module site.packaging.twomodules\n\n  references\n    site.packaging.twomodules.introduction::AnotherClass\n\n  defines package\n    version <- 1.0.0-0\n    description <- \"Simple samples\"\n    applyStandardIncludes <- true\n\n  defines program\n    HelloWorld()\n      stdout <- Stdout()\n      another <- AnotherClass()\n      stdout.println(`Hello, World ${another.greeting()}`)","expectedOutput":"Hello, World from another module\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"packaging/twomodules/packaging_twomodules_intro.ek9","url":"https://ek9.io/examples/packaging/twomodules/packaging_twomodules_intro.html","title":"Tier three: a second module, in a file of its own","code":"#!ek9\ndefines module site.packaging.twomodules.introduction\n\n  defines class\n    AnotherClass\n      greeting() as pure\n        <- rtn as String: \"from another module\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"packaging/version/packaging_version.ek9","url":"https://ek9.io/examples/packaging/version/packaging_version.html","title":"The version of the package being developed","code":"#!ek9\ndefines module site.packaging.version\n\n  defines package\n\n    version <- 2.3.14-0\n\n    description <- \"Example of different constants in different modules.\"\n\n    //No need for includeFiles for source code anymore.\n    applyStandardIncludes <- true\n\n    deps <- {\n      \"ekopen.network.support.utils\": \"1.6.1-9\",\n      \"ekopen.net.handy.tools\": \"3.2.1-0\"\n      }\n\n    excludeDeps <- {\n      \"ekopen.some.bad.dependency.pack\": \"ekopen.org.supertools.util\"\n      }\n\n  defines function\n    describe() as pure\n      <- rtn as String: \"site.packaging.version\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"packaging/withpackage/packaging_withpackage_hello.ek9","url":"https://ek9.io/examples/packaging/withpackage/packaging_withpackage_hello.html","title":"Tier two: the package block in the program's file","code":"#!ek9\ndefines module site.packaging.withpackage\n\n  defines package\n    version <- 1.0.0-0\n    description <- \"Simple samples\"\n    applyStandardIncludes <- true\n\n  defines program\n    HelloWorld()\n      stdout <- Stdout()\n      record <- BaseRecord()\n      duck <- Duck()\n      stdout.println(`Hello, World ${record.anything} ${duck.quack()}`)","expectedOutput":"Hello, World 90 Quack\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"packaging/withpackage/packaging_withpackage_traits.ek9","url":"https://ek9.io/examples/packaging/withpackage/packaging_withpackage_traits.html","title":"The shared code, unchanged","code":"#!ek9\ndefines module site.packaging.withpackage\n\n  defines record\n    BaseRecord as open\n      anything as Integer: 90\n\n      default operator ?\n\n  defines trait\n    Quack\n      quack() as pure\n        <- rtn as String?\n\n  defines class\n    Duck with trait of Quack\n      override quack() as pure\n        <- rtn as String: \"Quack\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"profiling/batch/dev/profiling_batch_tests.ek9","url":"https://ek9.io/examples/profiling/batch/dev/profiling_batch_tests.html","title":"Two tests, one large batch and one small","code":"#!ek9\ndefines module site.profiling.batch.tests\n\n  references\n    site.profiling.batch::batchProcess\n\n  defines program\n\n    @Test\n    SmallBatch()\n      assert batchProcess(3) > 0\n\n    @Test\n    LargeBatch()\n      assert batchProcess(2000) > 0","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"profiling/batch/profiling_batch.ek9","url":"https://ek9.io/examples/profiling/batch/profiling_batch.html","title":"A batch that calls a computation many times","code":"#!ek9\ndefines module site.profiling.batch\n\n  defines function\n\n    //The expensive one: most of the time is spent here, in its own loop\n    computeResult()\n      -> seed as Integer\n      <- result as Integer: 0\n      for step in 1 ... 200\n        result += seed * step\n\n    //The orchestrator: its time is mostly in the calls it makes\n    batchProcess()\n      -> count as Integer\n      <- total as Integer: 0\n      for item in 1 ... count\n        total += computeResult(item)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"quality/quality_delegation.ek9","url":"https://ek9.io/examples/quality/quality_delegation.html","title":"Composition with 'by' instead of a deep hierarchy","code":"#!ek9\ndefines module site.quality.delegation\n\n  defines trait\n    Printable\n      print() as abstract\n\n  defines class\n    ConsolePrinter with trait of Printable\n      override print()\n        Stdout().println(\"Console output\")\n\n    //Instead of: class MyClass extends DeepHierarchy\n    //Use delegation:\n    MyClass with trait of Printable by printer\n      printer as Printable: ConsolePrinter()\n\n      default operator ?\n\n  defines program\n    Delegate()\n      MyClass().print()","expectedOutput":"Console output\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"quality/quality_discarded_bad.ek9","url":"https://ek9.io/examples/quality/quality_discarded_bad.html","title":"Discarded return values","code":"#!ek9\ndefines module bad.site.quality.discarded\n\n  defines function\n\n    calculateTotal() as pure\n      -> items as List of Float\n      <- total as Float: Float(length items)\n\n    riskyParse()\n      <- rtn <- Result(\"OK\", Integer())\n\n    demo()\n      -> price as Float\n      items <- List() of Float\n\n      price.+(10.0)          //Computed value goes nowhere\n\n      calculateTotal(items)  //Pure call achieves nothing\n\n      riskyParse()           //Error silently swallowed","expectedOutput":null,"kind":"bad","errors":["E11050","E11051","E11052"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"quality/quality_discarded_good.ek9","url":"https://ek9.io/examples/quality/quality_discarded_good.html","title":"Return values captured or used","code":"#!ek9\ndefines module site.quality.discarded\n\n  defines function\n\n    calculateTotal() as pure\n      -> items as List of Float\n      <- total as Float: Float(length items)\n\n    riskyParse()\n      <- rtn <- Result(\"OK\", Integer())\n\n    demo()\n      -> price as Float\n      items <- List() of Float\n\n      total <- price + 10.0               //Assign the result\n      Stdout().println($total)\n      price += 10.0                       //Or use a mutating operator\n\n      orderTotal <- calculateTotal(items) //Assign the result\n      Stdout().println($orderTotal)\n\n      parseResult <- riskyParse()         //Handle the Result: check it, then take the value\n      if parseResult.isOk()\n        Stdout().println(parseResult.ok())\n\n  defines program\n    Discarded()\n      demo(42.0)","expectedOutput":"52.0\n0.0\nOK\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"quality/quality_named_args_bad.ek9","url":"https://ek9.io/examples/quality/quality_named_args_bad.html","title":"Ambiguous positional arguments","code":"#!ek9\ndefines module bad.site.quality.namedargs\n\n  defines function\n\n    connect()\n      ->\n        host as String\n        port as Integer\n        useSsl as Boolean\n        autoReconnect as Boolean\n      <- result as Boolean: host? and port? and (useSsl or autoReconnect)\n\n    schedule()\n      ->\n        jobName as String\n        targetPath as String\n        maxRetries as Integer\n        intervalMinutes as Integer\n      <- result as Boolean: jobName? and targetPath? and maxRetries > intervalMinutes\n\n    demo()\n      connected <- connect(\"db\", 5432, true, false)    //Which Boolean is which?\n\n      scheduled <- schedule(\"backup\", \"/data\", 3, 60)  //Which number is which?\n\n      Stdout().println(`${connected} ${scheduled}`)","expectedOutput":null,"kind":"bad","errors":["E11061","E11062"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"quality/quality_named_args_good.ek9","url":"https://ek9.io/examples/quality/quality_named_args_good.html","title":"Named arguments at ambiguous call sites","code":"#!ek9\ndefines module site.quality.namedargs\n\n  defines function\n\n    connect()\n      ->\n        host as String\n        port as Integer\n        useSsl as Boolean\n        autoReconnect as Boolean\n      <- result as Boolean: host? and port? and (useSsl or autoReconnect)\n\n    schedule()\n      ->\n        jobName as String\n        targetPath as String\n        maxRetries as Integer\n        intervalMinutes as Integer\n      <- result as Boolean: jobName? and targetPath? and maxRetries > intervalMinutes\n\n    demo()\n      connected <- connect(host: \"db\", port: 5432, useSsl: true, autoReconnect: false)\n      scheduled <- schedule(jobName: \"backup\", targetPath: \"/data\", maxRetries: 3, intervalMinutes: 60)\n      Stdout().println(`${connected} ${scheduled}`)\n\n  defines program\n    NamedArguments()\n      demo()","expectedOutput":"true false\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"quality/quality_names_bad.ek9","url":"https://ek9.io/examples/quality/quality_names_bad.html","title":"Non-descriptive names","code":"#!ek9\ndefines module bad.site.quality.names\n\n  defines function\n\n    fetch()\n      <- rtn as String: \"customer\"\n\n    process()\n      <- rtn as String?\n      temp <- \"hello\"     //What is temporary? User? Message? Session?\n      flag <- true        //What state? Valid? Active? Ready?\n      data <- fetch()     //What kind of data? User? Order? Config?\n      rtn: `${temp} ${flag} ${data}`","expectedOutput":null,"kind":"bad","errors":["E11031"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"quality/quality_names_good.ek9","url":"https://ek9.io/examples/quality/quality_names_good.html","title":"Descriptive names, and the short names that stay allowed","code":"#!ek9\ndefines module site.quality.names\n\n  defines function\n\n    fetch()\n      <- rtn as String: \"customer\"\n\n  defines class\n    Handler\n      describe() as pure\n        <- rtn as String: \"handles errors\"\n\n  defines program\n\n    NamesInUse()\n      stdout <- Stdout()\n\n      temporaryUser <- \"hello\"    //Clear: temporary user record\n      isPaymentValid <- true      //Clear: payment validation state\n      customerData <- fetch()     //Clear: customer data from the database\n      stdout.println(`${temporaryUser} ${isPaymentValid} ${customerData}`)\n\n      x <- 3.0                     //Cartesian coordinate\n      y <- 2.0                     //Cartesian coordinate\n      r <- sqrt (x*x + y*y)        //Polar radius\n      theta <- y.atan2(x)          //Polar angle\n      stdout.println(`${r} ${theta}`)\n\n      products <- List() of Integer\n      for i in 1 ... 3             //Standard loop counter\n        for j in 0 ... 2           //Nested loop counter\n          products += i * j\n      stdout.println($products)\n\n      connectionState <- \"active\"  //'state' is suffixed - specific\n      errorHandler <- Handler()    //'handler' is suffixed - specific\n      stdout.println(`${connectionState}`)\n\n      amount <- 100.00#USD         //The Money type makes 'amount' clear\n      distance <- 42.5km           //The Dimension type makes 'distance' clear\n      stdout.println(`${amount} ${distance}`)\n\n      paymentAmount <- 100.0       //Descriptive with a bare Float\n      stdout.println($paymentAmount)\n      stdout.println(errorHandler.describe())","expectedOutput":"hello true customer\n3.605551275463989 0.5880026035475675\n[0, 1, 2, 0, 2, 4, 0, 3, 6]\nactive\n100.00#USD 42.5km\n100.0\nhandles errors\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"quality/quality_reassign_bad.ek9","url":"https://ek9.io/examples/quality/quality_reassign_bad.html","title":"Reassigning a parameter","code":"#!ek9\ndefines module bad.site.quality.reassign\n\n  defines function\n\n    adjust()\n      -> count as Integer\n      <- result as Integer?\n\n      count := count + 1    //Error: cannot reassign a parameter\n      result: count * 2","expectedOutput":null,"kind":"bad","errors":["E08110"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"quality/quality_reassign_good.ek9","url":"https://ek9.io/examples/quality/quality_reassign_good.html","title":"A new variable instead","code":"#!ek9\ndefines module site.quality.reassign\n\n  defines function\n\n    adjust()\n      -> count as Integer\n      <- result as Integer?\n\n      adjusted <- count + 1    //Create a new variable instead\n      result: adjusted * 2","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"quality/quality_references_bad.ek9","url":"https://ek9.io/examples/quality/quality_references_bad.html","title":"References out of alphabetical order","code":"#!ek9\ndefines module bad.site.quality.references\n\n  references\n    org.ek9.lang::String      //'String' comes after 'Integer' and 'Boolean' alphabetically\n    org.ek9.lang::Integer     //Out of order\n    org.ek9.lang::Boolean     //Out of order\n\n  defines program\n    UseAll()\n      stdout <- Stdout()\n      stdout.println(`${String(\"text\")} ${Integer(1)} ${Boolean(true)}`)","expectedOutput":null,"kind":"bad","errors":["E11026"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"quality/quality_similar_bad.ek9","url":"https://ek9.io/examples/quality/quality_similar_bad.html","title":"Confusingly similar names of the same type","code":"#!ek9\ndefines module bad.site.quality.similar\n\n  defines function\n\n    describeOrder()\n      <- rtn as String?\n      userId <- \"customer-17\"\n      usersId <- \"order-42\"     //Similar to 'userId' - both String\n      rtn: `${userId} ${usersId}` //A bug waiting to happen: which one did you mean?\n\n    describeArticle()\n      <- rtn as String?\n      title <- \"Quality\"\n      titles <- \"Testing\"       //Both String - the compiler CAN'T catch it if you swap them\n      rtn: `${title} ${titles}`","expectedOutput":null,"kind":"bad","errors":["E11030"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"quality/quality_similar_good.ek9","url":"https://ek9.io/examples/quality/quality_similar_good.html","title":"Clearly distinct names, and similar names of different types","code":"#!ek9\ndefines module site.quality.similar\n\n  defines function\n\n    describeOrder()\n      <- rtn as String?\n      customerId <- \"customer-17\"\n      orderId <- \"order-42\"           //Clearly distinct\n      rtn: `${customerId} ${orderId}` //No ambiguity\n\n    describeArticle()\n      <- rtn as String?\n      title <- \"Quality\"\n      titles <- [\"Quality\", \"Testing\"] //Different types - the compiler catches a swap\n      rtn: `${title} ${titles}`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"quality/quality_unused_bad.ek9","url":"https://ek9.io/examples/quality/quality_unused_bad.html","title":"A parameter that is never used","code":"#!ek9\ndefines module bad.site.quality.unused\n\n  defines function\n\n    describe()\n      ->\n        used as String\n        notUsed as Integer    //Error: never referenced\n      <- result as String: used","expectedOutput":null,"kind":"bad","errors":["E08091"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"quality/references/quality_references.ek9","url":"https://ek9.io/examples/quality/references/quality_references.html","title":"References in alphabetical order","code":"#!ek9\ndefines module site.quality.references\n\n  references\n    site.quality.references.data::Model       //'data' first\n    site.quality.references.service::Client   //'service' second\n    site.quality.references.util::Helper      //'util' last\n\n  defines program\n    UseAll()\n      stdout <- Stdout()\n      stdout.println(`${Model().describe()}, ${Client().describe()}, ${Helper().describe()}`)","expectedOutput":"a model, a client, a helper\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"quality/references/quality_references_data.ek9","url":"https://ek9.io/examples/quality/references/quality_references_data.html","title":"A module the references example names: data","code":"#!ek9\ndefines module site.quality.references.data\n\n  defines class\n    Model\n      describe() as pure\n        <- rtn as String: \"a model\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"quality/references/quality_references_service.ek9","url":"https://ek9.io/examples/quality/references/quality_references_service.html","title":"A module the references example names: service","code":"#!ek9\ndefines module site.quality.references.service\n\n  defines class\n    Client\n      describe() as pure\n        <- rtn as String: \"a client\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"quality/references/quality_references_util.ek9","url":"https://ek9.io/examples/quality/references/quality_references_util.html","title":"A module the references example names: util","code":"#!ek9\ndefines module site.quality.references.util\n\n  defines class\n    Helper\n      describe() as pure\n        <- rtn as String: \"a helper\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"records/records_address.ek9","url":"https://ek9.io/examples/records/records_address.html","title":"The data clump extracted into a record","code":"#!ek9\ndefines module site.records.address\n\n  defines record\n\n    //After: the four values travel together as one record\n    Address\n      street as String: String()\n      city as String: String()\n      state as String: String()\n      zipCode as String: String()\n\n      Address()\n        ->\n          street as String\n          city as String\n          state as String\n          zipCode as String\n        this.street: street\n        this.city: city\n        this.state: state\n        this.zipCode: zipCode\n\n      default Address()\n\n      default operator ?\n\n  defines function\n\n    formatAddress()\n      -> address as Address\n      <- result as String: `${address.street}, ${address.city}, ${address.state} ${address.zipCode}`\n\n    isComplete()\n      -> address as Address\n      <- result as Boolean: address?\n\n    labelFor()\n      -> address as Address\n      <- result as String: `${address.zipCode}: ${address.street} ${address.city} ${address.state}`\n\n  defines program\n\n    ShowAddress()\n      stdout <- Stdout()\n      home <- Address(street: \"1 High Street\", city: \"Springfield\", state: \"IL\", zipCode: \"62701\")\n      stdout.println(formatAddress(home))\n      stdout.println(`Complete: ${isComplete(home)}`)\n      stdout.println(labelFor(home))","expectedOutput":"1 High Street, Springfield, IL 62701\nComplete: true\n62701: 1 High Street Springfield IL\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"records/records_customers.ek9","url":"https://ek9.io/examples/records/records_customers.html","title":"An abstract IdRecord and a CustomerDetail record with copy, merge and fuzzy match","code":"#!ek9\ndefines module site.records.customers\n  defines type\n\n    Index as Integer constrain as\n      > 0\n\n  defines function\n    defaultDateOfBirth()\n      <- rtn as Date: Date()\n\n    //IdRecord's '<=>' (by id) is the sameness of the whole hierarchy; a subtype cannot redefine it.\n    //Ordering customers by their details is therefore a comparator function, not a second '<=>'.\n    compareByBirthThenName()\n      ->\n        customer1 as CustomerDetail\n        customer2 as CustomerDetail\n      <- rtn as Integer: customer1.dateOfBirth <=> customer2.dateOfBirth\n\n      if rtn == 0\n        rtn: customer1.lastName <=> customer2.lastName\n      if rtn == 0\n        rtn: customer1.firstName <=> customer2.firstName\n\n  defines record\n\n    IdRecord as abstract\n      //We can support simple inference, but not complex expressions for fields/properties.\n      id <- Index()\n      createdAt as DateTime: SystemClock().dateTime()\n\n      IdRecord()\n        -> id as Index\n        require id?\n        this.id: id\n\n      operator $ as pure\n        <- rtn as String: `${$id} ${$createdAt}`\n      override operator ? as pure\n        <- rtn as Boolean: id?\n      //The sameness of every IdRecord: ==, <>, <, <=, > and >= are generated from it\n      operator <=> as pure\n        -> item as IdRecord\n        <- rtn as Integer: id <=> item.id\n      operator #? as pure\n        <- rtn as Integer: #? id\n\n    CustomerDetail extends IdRecord\n      firstName as String: String()\n      lastName as String: String()\n      dateOfBirth as Date: defaultDateOfBirth()\n\n      CustomerDetail()\n        ->\n          id as Index\n          firstName as String\n          lastName as String\n\n        super(id)\n        require firstName?\n        require lastName?\n        this.firstName: firstName\n        this.lastName: lastName\n\n      CustomerDetail()\n        ->\n          id as Index\n          dateOfBirth as Date\n\n        super(id)\n        require dateOfBirth?\n        this.dateOfBirth: dateOfBirth\n\n      CustomerDetail()\n        ->\n          id as Index\n          firstName as String\n          lastName as String\n          dateOfBirth as Date\n\n        super(id)\n        require firstName?\n        require lastName?\n        require dateOfBirth?\n        this.firstName: firstName\n        this.lastName: lastName\n        this.dateOfBirth: dateOfBirth\n\n      operator :=:\n        -> item as CustomerDetail\n        id :=: item.id\n        firstName :=: item.firstName\n        lastName :=: item.lastName\n        dateOfBirth :=: item.dateOfBirth\n\n      operator :~:\n        -> item as CustomerDetail\n        if not id?\n          id :=: item.id\n        if not firstName?\n          firstName :=: item.firstName\n        if not lastName?\n          lastName :=: item.lastName\n        if not dateOfBirth?\n          dateOfBirth :=: item.dateOfBirth\n\n      operator <~> as pure\n        -> item as CustomerDetail\n        //Use a fuzzy match on string version of date of birth first\n        <- rtn as Integer: ($this.dateOfBirth <~> $item.dateOfBirth) +\n        (this.lastName <~> item.lastName) +\n        (this.firstName <~> item.firstName)\n\n      operator #^ as pure\n        <- rtn as String: $this\n\n      override operator $ as pure\n        <- rtn as String: `${super.$()} ${firstName} ${lastName} ${$dateOfBirth}`\n      override operator ? as pure\n        <- rtn as Boolean: super.?() and firstName? and lastName? and dateOfBirth?\n\n  defines program\n    ShowCustomerRecords()\n      stdout <- Stdout()\n\n      unknownCustomer <- CustomerDetail()\n      stdout.println(`A customer with no details is set: ${unknownCustomer?}`)\n\n      customer1 <- CustomerDetail(id: Index(1), firstName: \"Gomez\", lastName: \"Addams\", dateOfBirth: 1963-06-08)\n      customer2 <- CustomerDetail(id: Index(2), firstName: \"Morticia\", lastName: \"Addams\", dateOfBirth: 1965-01-03)\n      customer3 <- CustomerDetail(id: Index(3), firstName: \"Pugsley\", lastName: \"Addams\", dateOfBirth: 1984-10-21)\n\n      //'<>' is generated from IdRecord's '<=>', so two customers differ by id.\n      stdout.println(`Gomez and Morticia are different records: ${customer1 <> customer2}`)\n\n      stdout.println(`Three Addams, ${customer1.firstName} ${customer2.firstName} and ${customer3.firstName}`)\n      //Some Addams we've not see before but born on same day or typo of Gomez?\n      customer4 <- CustomerDetail(id: Index(4), firstName: \"Goetez\", lastName: \"Addams\", dateOfBirth: 1963-06-08)\n      comp1 <- compareByBirthThenName(customer4, customer1)\n      comp2 <- compareByBirthThenName(customer4, customer2)\n      comp3 <- compareByBirthThenName(customer4, customer3)\n      stdout.println(`Compares [${comp1} ${comp2} ${comp3}]`)\n\n      best <- customer4 <~> customer1 < customer4 <~> customer2 <- customer1 else customer2\n      best: customer4 <~> customer3 < customer4 <~> best <- customer3 else best\n      stdout.println(`The best match for ${customer4.firstName} is ${best.firstName}`)\n\n      //full copy of the details\n      unknownCustomer :=: best\n      //now while objects differ contents are the same.\n      stdout.println(`After the copy, compared with Gomez: ${compareByBirthThenName(unknownCustomer, customer1)}`)\n\n      partialCustomer1 <- CustomerDetail(Index(1), \"Gomez\", \"Addams\")\n      partialCustomer2 <- CustomerDetail(Index(1), 1963-06-08)\n      //As both are partial the result of comparing them is unset!\n      stdout.println(`Two partial customers compare: ${compareByBirthThenName(partialCustomer1, partialCustomer2)?}`)\n\n      partialCustomer1 :~: partialCustomer2\n      //After merging the two should match Gomez.\n      stdout.println(`After the merge, compared with Gomez: ${compareByBirthThenName(partialCustomer1, customer1)}`)","expectedOutput":"A customer with no details is set: false\nGomez and Morticia are different records: true\nThree Addams, Gomez Morticia and Pugsley\nCompares [-8 -1 -1]\nThe best match for Goetez is Gomez\nAfter the copy, compared with Gomez: 0\nTwo partial customers compare: false\nAfter the merge, compared with Gomez: 0\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"records/records_data_clump.ek9","url":"https://ek9.io/examples/records/records_data_clump.html","title":"The same four parameters across three functions","code":"#!ek9\ndefines module bad.site.records.dataclump\n\n  defines function\n\n    //Before: the same four parameters repeated across functions\n    formatAddress()\n      ->\n        street as String\n        city as String\n        state as String\n        zipCode as String\n      <- result as String: `${street}, ${city}, ${state} ${zipCode}`\n\n    isComplete()\n      ->\n        street as String\n        city as String\n        state as String\n        zipCode as String\n      <- result as Boolean: street? and city? and state? and zipCode?\n\n    labelFor()\n      ->\n        street as String\n        city as String\n        state as String\n        zipCode as String\n      <- result as String: `${zipCode}: ${street} ${city} ${state}`","expectedOutput":null,"kind":"bad","errors":["E11053"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"records/records_default_operator.ek9","url":"https://ek9.io/examples/records/records_default_operator.html","title":"Default operators on a record","code":"#!ek9\ndefines module site.records.defaultoperator\n\n  defines record\n\n    Coordinates\n      latitude as Float: Float()\n      longitude as Float: Float()\n\n      default Coordinates()\n\n      Coordinates()\n        ->\n          latitude as Float\n          longitude as Float\n        this.latitude: latitude\n        this.longitude: longitude\n\n      //EK9 to provide default implementations\n      default operator\n\n  defines program\n\n    DefaultOperator()\n      stdout <- Stdout()\n\n      first <- Coordinates(51.5, -0.12)\n      second <- Coordinates(51.5, -0.12)\n      stdout.println(`${first} ${first == second} ${first <=> second} ${first?}`)","expectedOutput":"Coordinates(latitude=51.5, longitude=-0.12) true 0 true\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"sanitized/context/sanitized_context.ek9","url":"https://ek9.io/examples/sanitized/context/sanitized_context.html","title":"Sanitizing with a SanitizationContext","code":"#!ek9\ndefines module site.sanitized.context\n\n  defines function\n\n    processData()\n      -> text as String\n      Stdout().println(text)\n\n  defines program\n    ContextExample()\n      sanitizer <- InputSanitizer()\n\n      //Create a context with rich metadata\n      context <- SanitizationContext(\n        timestamp: SystemClock().dateTime(),\n        service: \"UserService\",\n        operation: \"getUser\",\n        fieldName: \"userId\",\n        fieldSource: \"PATH\",\n        sourceIp: \"192.168.1.100\",\n        traceId: \"trace-abc-123\"\n      )\n\n      userInput <- \"' OR '1'='1\"\n\n      //Sanitize with context - the log carries the context fields\n      result <- sanitizer.sanitize(userInput, context)\n      if result?\n        processData(result)\n\n      //A partly set context is unset as a record, but the log still carries the fields that ARE set\n      partial <- SanitizationContext(\n        timestamp: SystemClock().dateTime(),\n        service: \"UserService\",\n        operation: \"getUser\",\n        fieldName: String(),\n        fieldSource: String(),\n        sourceIp: \"192.168.1.100\",\n        traceId: String()\n      )\n      partialResult <- sanitizer.sanitize(userInput, partial)\n      if partialResult?\n        processData(partialResult)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"sanitized/logformats/sanitized_logformats.ek9","url":"https://ek9.io/examples/sanitized/logformats/sanitized_logformats.html","title":"A program that meets one SQL injection and one XSS attempt","code":"#!ek9\ndefines module site.sanitized.logformats\n\n  defines program\n    MeetThreats()\n      //The default reporter is stderr; each threat is logged in the configured format\n      sanitizer <- InputSanitizer()\n      sqlInjection <- sanitizer.sanitize(String(\"' OR '1'='1\"))\n      crossSiteScript <- sanitizer.sanitize(String(\"<script>alert(1)</script>\"))\n      //Both are rejected: each result is unset\n      Stdout().println(`Both rejected: ${not (sqlInjection? or crossSiteScript?)}`)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"sanitized/sanitized_alias_bad.ek9","url":"https://ek9.io/examples/sanitized/sanitized_alias_bad.html","title":"Assigning a sanitized parameter directly to a local","code":"#!ek9\ndefines module bad.site.sanitized.alias\n\n  defines function\n\n    processInput()\n      -> userInput as sanitized String\n      local <- userInput       //'local' would be an alias of 'userInput'\n      local += \" modified\"     //...and this would modify 'userInput' too\n      Stdout().println(local)","expectedOutput":null,"kind":"bad","errors":["E07930"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"sanitized/sanitized_alias_good.ek9","url":"https://ek9.io/examples/sanitized/sanitized_alias_good.html","title":"An explicit copy instead","code":"#!ek9\ndefines module site.sanitized.alias\n\n  defines function\n\n    processInput()\n      -> userInput as sanitized String\n      local <- String(userInput)  //OK: an explicit copy\n      local += \" modified\"        //Only affects 'local'\n      Stdout().println(local)\n\n  defines program\n    CopyNotAlias()\n      processInput(\"Ada\")","expectedOutput":"Ada modified\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"sanitized/sanitized_callsite_bad.ek9","url":"https://ek9.io/examples/sanitized/sanitized_callsite_bad.html","title":"sanitized at a call site","code":"#!ek9\ndefines module bad.site.sanitized.callsite\n\n  defines function\n\n    processInput()\n      -> userInput as sanitized String\n      <- rtn as String: String(userInput)\n\n    caller()\n      -> userInput as String\n      result <- processInput(sanitized userInput)  //The caller can't specify sanitization\n      Stdout().println(result)","expectedOutput":null,"kind":"bad","errors":["E07942"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"sanitized/sanitized_capture_bad.ek9","url":"https://ek9.io/examples/sanitized/sanitized_capture_bad.html","title":"sanitized on a capture","code":"#!ek9\ndefines module bad.site.sanitized.capture\n\n  defines function\n\n    BaseHandler() as abstract\n      <- rtn as String?\n\n    makeHandler()\n      -> userInput as String\n      <- rtn as BaseHandler?\n      rtn: (sanitized userInput) is BaseHandler as function  //A capture is already inside the trust boundary\n        rtn: String(userInput)","expectedOutput":null,"kind":"bad","errors":["E07941"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"sanitized/sanitized_cmdline.ek9","url":"https://ek9.io/examples/sanitized/sanitized_cmdline.html","title":"Sanitizing command-line arguments","code":"#!ek9\ndefines module site.sanitized.cmdline\n\n  defines function\n\n    processFile()\n      -> fileName as String\n      Stdout().println(`Processing ${fileName}`)\n\n  defines program\n    ProcessFiles()\n      -> argv as List of String\n\n      sanitizer <- InputSanitizer(Stderr())\n\n      for commandLineArgument in argv\n        cleanArgument <- sanitizer.sanitize(commandLineArgument)\n        if cleanArgument?\n          processFile(cleanArgument)\n        else\n          Stderr().println(\"Rejected potentially dangerous argument\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"sanitized/sanitized_constructors.ek9","url":"https://ek9.io/examples/sanitized/sanitized_constructors.html","title":"InputSanitizer constructors","code":"#!ek9\ndefines module site.sanitized.constructors\n\n  defines function\n\n    safeOnEveryRoute()\n      -> userInput as String\n      <- rtn as Boolean: true\n\n      //Default - always logs threats to stderr\n      defaultSanitizer <- InputSanitizer()\n      rtn: rtn and defaultSanitizer.isSafe(userInput)\n\n      //With an explicit reporter (here, stderr)\n      stderrSanitizer <- InputSanitizer(Stderr())\n      rtn: rtn and stderrSanitizer.isSafe(userInput)\n\n      //Log to a file: the file's output is a resource, so the try owns it and closes it\n      try\n        -> securityLog <- TextFile(\"security.log\").output()\n        fileSanitizer <- InputSanitizer(securityLog)\n        rtn: rtn and fileSanitizer.isSafe(userInput)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"sanitized/sanitized_declaration_bad.ek9","url":"https://ek9.io/examples/sanitized/sanitized_declaration_bad.html","title":"sanitized on a variable declaration","code":"#!ek9\ndefines module bad.site.sanitized.declaration\n\n  defines function\n\n    getValue()\n      <- rtn as String: \"Ada\"\n\n    caller()\n      name <- sanitized getValue()  //Wrong place: sanitize the parameters of the function that receives input\n      Stdout().println(name)","expectedOutput":null,"kind":"bad","errors":["E07943"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"sanitized/sanitized_methods.ek9","url":"https://ek9.io/examples/sanitized/sanitized_methods.html","title":"InputSanitizer methods","code":"#!ek9\ndefines module site.sanitized.methods\n\n  defines function\n\n    processData()\n      -> text as String\n      Stdout().println(text)\n\n    handleThreatDetection()\n      Stderr().println(\"Threat detected\")\n\n    logThreat()\n      -> threatKinds as String\n      Stderr().println(threatKinds)\n\n  defines program\n    SanitizerExample()\n      sanitizer <- InputSanitizer(Stderr())\n\n      //Sanitize input - returns unset if a threat is detected\n      userInput <- \"some user input\"\n      result <- sanitizer.sanitize(userInput)\n      if result?\n        //Safe to use\n        processData(result)\n      else\n        //Threat detected, handle appropriately\n        handleThreatDetection()\n\n      //Check safety without modification\n      if sanitizer.isSafe(userInput)\n        processData(userInput)\n\n      //Get the threat type(s) as a comma-separated string\n      threat <- sanitizer.detectThreat(userInput)\n      if threat?\n        logThreat(threat)  //e.g. \"SQL_INJECTION, XSS\"\n\n      //For environment variables (skip path traversal checks)\n      envValue <- EnvVars().get(\"CONFIG_PATH\")\n      if envValue?\n        cleanEnvValue <- sanitizer.sanitizeWithoutPathChecks(envValue)\n        processData(cleanEnvValue)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"sanitized/sanitized_modifier.ek9","url":"https://ek9.io/examples/sanitized/sanitized_modifier.html","title":"The sanitized parameter modifier","code":"#!ek9\ndefines module site.sanitized.modifier\n\n  defines function\n\n    executeQuery()\n      -> sql as sanitized String\n      <- result as String?\n      //The 'sql' parameter is sanitized on entry,\n      //before any of this function's code runs - preventing SQL injection\n      result: `executed ${sql}`\n\n    processUserInput()\n      ->\n        name as sanitized String\n        comment as sanitized String\n      <- success as Boolean?\n      //Both parameters are sanitized before use: a threat leaves one unset\n      success: name? and comment?\n\n    processInput()\n      -> userInput as sanitized String  //OK: sanitized at the definition - the target site\n      <- rtn as String: userInput\n\n  defines program\n    SanitizedInUse()\n      stdout <- Stdout()\n      stdout.println(executeQuery(\"customer 42\"))\n      stdout.println($processUserInput(\"Ada\", \"Lovely day\"))\n      stdout.println(processInput(\"Ada\"))","expectedOutput":"executed customer 42\ntrue\nAda\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"sanitized/sanitized_practices.ek9","url":"https://ek9.io/examples/sanitized/sanitized_practices.html","title":"Best practices: sanitize user input by default, handle unset, and environment variables","code":"#!ek9\ndefines module site.sanitized.practices\n\n  defines function\n\n    //GOOD: default to sanitized for user input\n    processUserData()\n      -> input as sanitized String\n      <- rtn as String: String(input)\n\n    //Only omit sanitized for trusted internal data\n    processInternalData()\n      -> trustedInput as String\n      <- rtn as String: trustedInput\n\n    doCreateUser()\n      -> username as String\n      <- created as Boolean: username?\n\n    logValidationError()\n      -> message as String\n      Stderr().println(message)\n\n    createUser()\n      -> username as sanitized String\n      <- result as Boolean?\n\n      if username?\n        //Safe to process\n        result: doCreateUser(username)\n      else\n        //Threat detected - apply the normal business validation message:\n        //defence in depth without leaking what was detected\n        result: false\n        logValidationError(\"Invalid username format\")\n\n    configurationPath()\n      <- rtn as String: String()\n\n      sanitizer <- InputSanitizer(Stderr())\n      envVars <- EnvVars()\n\n      //Path traversal patterns are legitimate in environment variables\n      configPath <- envVars.get(\"CONFIG_PATH\")\n      if configPath?\n        rtn: sanitizer.sanitizeWithoutPathChecks(configPath)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"sanitized/sanitized_sensitive.ek9","url":"https://ek9.io/examples/sanitized/sanitized_sensitive.html","title":"Sensitive values and the Privileged trait","code":"#!ek9\ndefines module site.sanitized.sensitive\n\n  defines function\n\n    doHttpCall() as pure\n      -> header as String\n      <- response as String: `called with a ${length header} character header`\n\n  defines class\n\n    HttpClient with trait of Privileged\n      apiKey as Sensitive?\n\n      HttpClient()\n        -> key as Sensitive\n        apiKey: key\n\n      default private HttpClient()\n\n      sendRequest()\n        <- response as String: String()\n        //reveal() only works because HttpClient has the Privileged trait\n        if apiKey?\n          header <- apiKey.reveal()\n          response: doHttpCall(header)\n\n      default operator ?\n\n  defines function\n\n    demo()\n      env <- EnvVars()\n      //sensitiveGet() is the ONLY way to create a set Sensitive value\n      key <- env.sensitiveGet(\"API_KEY\")\n      if key?\n        client <- HttpClient(key)\n        result <- client.sendRequest()\n\n        stdout <- Stdout()\n        //Safe: printing the key shows \"***REDACTED***\", not the secret\n        stdout.println(`Key: ${key}`)\n        if result?\n          stdout.println(result)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"sanitized/sanitized_service.ek9","url":"https://ek9.io/examples/sanitized/sanitized_service.html","title":"sanitized path and query parameters in a web service","code":"#!ek9\ndefines module site.sanitized.service\n\n  defines function\n\n    userResponse() as pure\n      -> detail as String\n      <- response as HTTPResponse: (detail) with trait of HTTPResponse\n        override content()\n          <- rtn as Bytes: Bytes().withUtf8(detail)\n        override status() as pure\n          <- rtn as Integer: 200\n        override contentType() as pure\n          <- rtn as String: \"text/plain\"\n        override cacheControl() as pure\n          <- rtn as String: \"no-cache\"\n        override contentLanguage() as pure\n          <- rtn as String: \"en\"\n        default operator ?\n\n  defines service\n\n    UserService for :/users open\n\n      getUser() as GET for :/{userId}\n        -> userId as sanitized String :=: PATH\n        <- response as HTTPResponse: userResponse(userId)\n        //userId is sanitized before any of this method's code runs\n\n      searchUsers() as GET for :/search\n        -> query as sanitized String :=: QUERY \"query\"\n        <- response as HTTPResponse: userResponse(query)\n        //and so is the query parameter","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"sanitized/sanitized_textfile.ek9","url":"https://ek9.io/examples/sanitized/sanitized_textfile.html","title":"Reading a file named by user input","code":"#!ek9\ndefines module site.sanitized.textfile\n\n  defines function\n    readUserFile()\n      -> filename as sanitized String\n      <- content as String: String()\n\n      //A path traversal attempt leaves 'filename' unset, so nothing is read\n      if filename?\n        content: cat TextFile(filename).input() | collect as String","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"standardTypes/standardTypes_data_correlation.ek9","url":"https://ek9.io/examples/standardTypes/standardTypes_data_correlation.html","title":"Correlating a named file with Standard Input","code":"#!ek9\ndefines module site.standardTypes.dataCorrelation\n\n  defines program\n\n    DataCorrelation()\n      -> argv as List of String\n\n      stdin <- Stdin()\n      stdout <- Stdout()\n      stderr <- Stderr()\n\n      optionsHandler <- OptionsHandler()\n      options <- optionsHandler.processCommandLine(argv)\n\n      verboseMode <- options contains \"-v\"\n      debugLevel <- optionsHandler.processDebugLevel(verboseMode, options.getOrDefault(\"-d\", \"\"))\n\n      //Use NamedFileProcessor for clean separation of concerns\n      filename <- Optional(options.getOrDefault(\"-f\", \"\"))\n      namedFileContents <- NamedFileProcessor(verboseMode, debugLevel).processNamedFile(filename)\n\n      if verboseMode\n        stderr.println(`Process id is [${OS().pid()}]`)\n      if verboseMode or debugLevel > 0\n        stderr.println(`Loaded ${$ length namedFileContents} records from named file`)\n\n      setupSignalHandling(verboseMode, debugLevel)\n\n      validLine <- createLineValidator(stderr, debugLevel)\n      toEntry <- createStdinLineHandler(stderr, debugLevel)\n      byMerging <- createCustomerRecordMerger(stderr, debugLevel, namedFileContents)\n\n      if debugLevel > 1\n        stderr.println(\"Ready to start processing Standard Input\")\n\n      outputHeader(verboseMode, debugLevel, stdout)\n      cat stdin | filter by validLine | map toEntry | filter by validEntry | map byMerging > stdout\n\n      if debugLevel > 1\n        stderr.println(\"Standard Input processing complete\")\n\n  defines function\n\n    lineValidator() as pure abstract\n      -> line as String\n      <- rtn as Boolean?\n\n    lineToCustomerRecord() as pure open\n      -> line as String\n      <- rtn as DictEntry of (String, CustomerRecord)?\n      require line?\n      rtn: DictEntry() of (String, CustomerRecord)\n\n    customerRecordMerger() as abstract\n      -> entry as DictEntry of (String, CustomerRecord)\n      <- rtn as String?\n\n    createLineValidator()\n      ->\n        stderr as Stderr\n        debugLevel as Integer\n      <-\n        validator as lineValidator?\n\n      validator: (stderr, debugLevel) is lineValidator as pure function\n        rtn :=? line is not empty and #<line != '#'\n        if debugLevel > 1 and not rtn\n          stderr.println(`Discarding [${line}]`)\n\n    createStdinLineHandler()\n      ->\n        stderr as Stderr\n        debugLevel as Integer\n      <-\n        processor as lineToCustomerRecord?\n\n      processor: (stderr, debugLevel) is lineToCustomerRecord as pure function\n        rtn: DictEntry() of (String, CustomerRecord)\n        traceLevel <- 3\n        expectedFieldCount <- 4\n\n        splitLine <- line.split(/,/)\n        if debugLevel == traceLevel\n          stderr.println(`About to split stdin line [${line}]`)\n\n        if length of splitLine == expectedFieldCount\n          id <- splitLine.getOrDefault(0, \"\").trim()\n          firstname <- splitLine.getOrDefault(1, \"\").trim()\n          lastname <- splitLine.getOrDefault(2, \"\").trim()\n          dobStr <- splitLine.getOrDefault(3, \"\").trim()\n          if id is not empty and firstname is not empty and lastname is not empty and dobStr is not empty\n            dob <- $getAsDateTime(id, false, dobStr)\n            if dob?\n              entryValue <- CustomerRecord(id: id, firstName: firstname, lastName: lastname, email: String(), dob: dob, lastPurchase: String())\n              if debugLevel == traceLevel\n                stderr.println(`Line [${line}] processed`)\n              rtn :=? DictEntry(id, entryValue)\n\n        if not rtn?\n          stderr.println(`Invalid line [${line}]`)\n\n    getAsDateTime() as pure\n      ->\n        id as String\n        throwException as Boolean\n        aDateInput as String //expecting YYYYMMDD\n      <-\n        rtn as DateTime: DateTime()\n\n      expectedDateParts <- 3\n      group <- aDateInput.group(/(\\d{4})(\\d{2})(\\d{2})/)\n      if length group == expectedDateParts\n        dateStr <- cat group | join with dashSeparated | collect as String\n        rtn :=? DateTime(Date(dateStr))\n      else if throwException\n        throw Exception(`Id [${id}] Invalid date [${aDateInput}]`, 2)\n      else\n        Stderr().println(`Id [${id}] Invalid date [${aDateInput}]`)\n\n    validEntry() as pure\n      -> entry as DictEntry of (String, CustomerRecord)\n      <- rtn as Boolean: entry?\n\n    dashSeparated() as pure\n      ->\n        firstPart String\n        secondPart String\n      <-\n        rtn as String: firstPart? and secondPart? <- `${firstPart}-${secondPart}` : String()\n\n    outputFormatSeparated() as pure\n      ->\n        firstPart String\n        secondPart String\n      <-\n        rtn as String: firstPart? and secondPart? <- `${firstPart}, ${secondPart}` : String()\n\n    setupSignalHandling()\n      ->\n        verboseMode as Boolean\n        debugLevel as Integer\n\n      terminationHandler <- (verboseMode, debugLevel) is SignalHandler as function\n        result: 1 //The error code to terminate with\n        if verboseMode or debugLevel > 0\n          Stderr().println(`Handled Terminal Signal [${signal}]`)\n\n      terminations <- Signals().register([\"HUP\", \"ABRT\"], terminationHandler)\n      if terminations not contains \"HUP\"\n        Stderr().println(\"HUP Signal not supported\")\n      if terminations not contains \"ABRT\"\n        Stderr().println(\"ABRT Signal not supported\")\n\n      debugHandler <- (verboseMode, debugLevel) is SignalHandler as function\n        maxDebugLevel <- 3\n        result: Integer() //Note the Integer is not set so process will not terminate\n        if signal == \"USR1\" and debugLevel < maxDebugLevel\n          debugLevel++\n        else if signal == \"USR2\" and debugLevel > 0\n          debugLevel--\n        if verboseMode or debugLevel > 0\n          Stderr().println(`Handled Info Signal [${signal}] Debug Level now [${debugLevel}]`)\n\n      debugs <- Signals().register([\"USR1\", \"USR2\"], debugHandler)\n      if debugs not contains \"USR1\"\n        Stderr().println(\"USR1 Signal not supported\")\n      if debugs not contains \"USR2\"\n        Stderr().println(\"USR2 Signal not supported\")\n\n    outputHeader()\n      ->\n        verboseMode as Boolean\n        debugLevel as Integer\n        stdout as Stdout\n\n      detailedDebugLevel <- 2\n      enGB <- Locale(\"en_GB\")\n      if verboseMode or debugLevel > detailedDebugLevel\n        Stderr().println(`About to create output header with locale ${enGB}`)\n\n      envVars <- EnvVars()\n      user <- envVars contains \"USER\" <- envVars.get(\"USER\") else envVars.get(\"USERNAME\")\n      dateTime <- enGB.mediumFormat(SystemClock().dateTime())\n\n      stdout.println(`#Created by ${user} on ${dateTime}`)\n      stdout.println(\"#id, firstName, lastName, emailAddress, dateOfBirth, dateLastPurchase\")\n\n    createCustomerRecordMerger()\n      ->\n        stderr as Stderr\n        debugLevel as Integer\n        namedFileContents as Dict of (String, CustomerRecord)\n      <-\n        merge as customerRecordMerger?\n\n      merge: (stderr, debugLevel, namedFileContents) is customerRecordMerger\n        traceLevel <- 3\n        rtn: String() //Output will be unset by default and there for not output\n        id <- entry.key()\n        if debugLevel == traceLevel\n          stderr.println(`Merging id [${id}]`)\n        if namedFileContents contains id\n          stdinEntry <- entry.value()\n          namedFileEntry <- namedFileContents.getOrDefault(id, CustomerRecord())\n          stdinEntry :~: namedFileEntry\n          rtn := $stdinEntry\n        else\n          stderr.println(`Not merging [${id}] as named file does not contain id`)\n\n  defines class\n\n    OptionsHandler\n\n      processCommandLine() as pure\n        -> arguments as List of String\n        <- options as Dict of (String, String)?\n\n        getopts <- setupGetOpt(\":\")\n        options :=? getopts.options(arguments)\n\n      private setupGetOpt() as pure\n        -> rqParam as String\n        <- getopts as GetOpt?\n\n        supportedOptions <- setupSupportedOptions(rqParam)\n        usage <- setupUsage()\n        getopts :=? GetOpt(rqParam, supportedOptions, usage)\n\n      private setupSupportedOptions() as pure\n        -> rqParam as String\n        <- rtn as Dict of (String, String)?\n\n        rtn :=? {\n          \"-v\": String(),\n          \"-f\": rqParam,\n          \"-d\": rqParam\n          }\n\n      private setupUsage() as pure\n        <- rtn as String?\n\n        desc <- \"Invalid option, only those list below are supported:\"\n        verbose <- \"-v, verbose\"\n        filename <- \"-f filename, use file of filename (mandatory option)\"\n        debug <- \"-d level, use of debugging\"\n        rtn :=? `${desc}\\n${verbose}\\n${filename}\\n${debug}`\n\n      processDebugLevel()\n        ->\n          verboseMode as Boolean\n          level as String\n        <-\n          rtn as Integer: 0 //default to zero\n\n        maxDebugLevel <- 3\n        debugLevel <- Integer(level)\n\n        rtn := (debugLevel in 0 ... maxDebugLevel) <- debugLevel else 0\n\n        if verboseMode and (debugLevel not in 0 ... maxDebugLevel)\n          Stderr().println(`Debug level ${debugLevel} not supported - reverting to debug level '0'`)\n\n    NamedFileProcessor\n      verboseMode as Boolean: false\n      debugLevel as Integer: Integer()\n\n      NamedFileProcessor()\n        ->\n          verboseMode as Boolean\n          debugLevel as Integer\n        this.verboseMode = verboseMode\n        this.debugLevel = debugLevel\n\n      processNamedFile()\n        -> filename as Optional of String\n        <- rtn <- Dict() of (String, CustomerRecord)\n\n        stderr <- Stderr()\n        if filename?\n          namedFile <- getNamedFile(filename.get())\n          validLine <- createLineValidator(stderr, debugLevel)\n          toEntry <- createNamedFileLineHandler(stderr, debugLevel)\n\n          if verboseMode or debugLevel > 0\n            stderr.println(`About to start processing [${namedFile}]`)\n\n          cat namedFile.input() | filter by validLine | map toEntry > rtn\n\n          if debugLevel > 1\n            stderr.println(`Processing [${namedFile}] complete`)\n        else\n          throw Exception(\"Filename of 'named file' is required\", 2)\n\n      private getNamedFile()\n        -> filename as String\n        <- rtn as TextFile: TextFile()\n\n        filePath <- FileSystemPath(filename)\n        rtn := filePath.isAbsolute() <- TextFile(filePath) else TextFile(FileSystem().cwd() + filePath)\n        if not rtn?\n          throw Exception(`${filePath} is not an existing file`, 2)\n        if not rtn.isReadable()\n          throw Exception(`${rtn} is not readable`, 2)\n\n      private createNamedFileLineHandler() as pure\n        ->\n          stderr as Stderr\n          debugLevel as Integer\n        <-\n          processor as lineToCustomerRecord?\n\n        processor :=? (stderr, debugLevel) is lineToCustomerRecord as pure function\n          traceLevel <- 3\n          expectedFieldCount <- 4\n          splitLine <- line.split(/:/)\n          if debugLevel == traceLevel\n            stderr.println(`About to split line [${line}]`)\n\n          if length of splitLine != expectedFieldCount\n            throw Exception(`Invalid line [${line}]`, 2)\n          id <- splitLine.getOrDefault(0, \"\").trim()\n          if id is empty\n            throw Exception(`Invalid line [${line}] empty ID`, 2)\n\n          emailAddress <- splitLine.getOrDefault(1, \"\").trim()\n          if emailAddress not matches /[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$/\n            throw Exception(`Id [${id}] Invalid email address [${emailAddress}]`, 2)\n\n          dateLastPurchase <- $getAsDateTime(id, true, splitLine.getOrDefault(3, \"\").trim())\n\n          entryValue <- CustomerRecord(id: id, firstName: String(), lastName: String(), email: emailAddress, dob: String(), lastPurchase: dateLastPurchase)\n          if debugLevel == traceLevel\n            stderr.println(`Named file line [${line}] processed`)\n\n          rtn :=? DictEntry(id, entryValue)\n\n      default operator ?\n\n  defines record\n\n    CustomerRecord\n      id <- String()\n      firstName <- String()\n      lastName <- String()\n      email <- String()\n      dob <- String()\n      lastPurchase <- String()\n\n      default CustomerRecord() as pure\n\n      CustomerRecord() as pure\n        ->\n          id as String\n          firstName as String\n          lastName as String\n          email as String\n          dob as String\n          lastPurchase as String\n        this.id :=? String(id)\n        this.firstName :=? String(firstName)\n        this.lastName :=? String(lastName)\n        this.email :=? String(email)\n        this.dob :=? String(dob)\n        this.lastPurchase :=? String(lastPurchase)\n\n      override operator ? as pure\n        <- rtn as Boolean: id?\n\n      operator :~:\n        -> other as CustomerRecord\n\n        id :=? String(other.id)\n        firstName :=? String(other.firstName)\n        lastName :=? String(other.lastName)\n        email :=? String(other.email)\n        dob :=? String(other.dob)\n        lastPurchase :=? String(other.lastPurchase)\n\n      operator $ as pure\n        <- rtn as String: cat [id, firstName, lastName, email, dob, lastPurchase]\n          | join with outputFormatSeparated\n          | collect as String","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"standardTypes/standardTypes_data_correlation_inlined.ek9","url":"https://ek9.io/examples/standardTypes/standardTypes_data_correlation_inlined.html","title":"The named file processing inlined into the program","code":"#!ek9\ndefines module bad.site.standardTypes.dataCorrelationInlined\n\n  defines program\n\n    DataCorrelation()\n      -> argv as List of String\n\n      stdin <- Stdin()\n      stdout <- Stdout()\n      stderr <- Stderr()\n\n      optionsHandler <- OptionsHandler()\n      options <- optionsHandler.processCommandLine(argv)\n\n      verboseMode <- options contains \"-v\"\n      debugLevel <- optionsHandler.processDebugLevel(verboseMode, options.getOrDefault(\"-d\", \"\"))\n\n      debugTraceLevel <- 3\n      expectedFieldCount <- 4\n\n      //All the named file processing inlined here, rather than in NamedFileProcessor\n      filename <- options.getOrDefault(\"-f\", \"\")\n      if not filename?\n        throw Exception(\"Filename of 'named file' is required\", 2)\n      filePath <- FileSystemPath(filename)\n      namedFile <- filePath.isAbsolute() <- TextFile(filePath) else TextFile(FileSystem().cwd() + filePath)\n      if not namedFile?\n        throw Exception(`${filePath} is not an existing file`, 2)\n      if not namedFile.isReadable()\n        throw Exception(`${namedFile} is not readable`, 2)\n\n      if verboseMode or debugLevel > 0\n        stderr.println(`About to start processing [${namedFile}]`)\n\n      namedFileContents <- Dict() of (String, CustomerRecord)\n      try\n        -> input <- namedFile.input()\n        while input?\n          line <- input.next()\n          if line is not empty and #<line != '#'\n            splitLine <- line.split(/:/)\n            if debugLevel == debugTraceLevel\n              stderr.println(`About to split line [${line}]`)\n\n            if length of splitLine != expectedFieldCount\n              throw Exception(`Invalid line [${line}]`, 2)\n            id <- splitLine.getOrDefault(0, \"\").trim()\n            if id is empty\n              throw Exception(`Invalid line [${line}] empty ID`, 2)\n\n            emailAddress <- splitLine.getOrDefault(1, \"\").trim()\n            if emailAddress not matches /[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$/\n              throw Exception(`Id [${id}] Invalid email address [${emailAddress}]`, 2)\n\n            dateLastPurchase <- $getAsDateTime(id, true, splitLine.getOrDefault(3, \"\").trim())\n\n            entryValue <- CustomerRecord(id: id, firstName: String(), lastName: String(), email: emailAddress, dob: String(), lastPurchase: dateLastPurchase)\n            if debugLevel == debugTraceLevel\n              stderr.println(`Named file line [${line}] processed`)\n\n            namedFileContents += DictEntry(id, entryValue)\n\n          else if debugLevel > 1\n            stderr.println(`Discarding [${line}]`)\n\n      if verboseMode\n        stderr.println(`Process id is [${OS().pid()}]`)\n      if verboseMode or debugLevel > 0\n        stderr.println(`Loaded ${$ length namedFileContents} records from named file`)\n\n      setupSignalHandling(verboseMode, debugLevel)\n\n      validLine <- createLineValidator(stderr, debugLevel)\n      toEntry <- createStdinLineHandler(stderr, debugLevel)\n      byMerging <- createCustomerRecordMerger(stderr, debugLevel, namedFileContents)\n\n      if debugLevel > 1\n        stderr.println(\"Ready to start processing Standard Input\")\n\n      outputHeader(verboseMode, debugLevel, stdout)\n      cat stdin | filter by validLine | map toEntry | filter by validEntry | map byMerging > stdout\n\n      if debugLevel > 1\n        stderr.println(\"Standard Input processing complete\")\n\n  defines function\n\n    lineValidator() as pure abstract\n      -> line as String\n      <- rtn as Boolean?\n\n    lineToCustomerRecord() as pure open\n      -> line as String\n      <- rtn as DictEntry of (String, CustomerRecord)?\n      require line?\n      rtn: DictEntry() of (String, CustomerRecord)\n\n    customerRecordMerger() as abstract\n      -> entry as DictEntry of (String, CustomerRecord)\n      <- rtn as String?\n\n    createLineValidator()\n      ->\n        stderr as Stderr\n        debugLevel as Integer\n      <-\n        validator as lineValidator?\n\n      validator: (stderr, debugLevel) is lineValidator as pure function\n        rtn :=? line is not empty and #<line != '#'\n        if debugLevel > 1 and not rtn\n          stderr.println(`Discarding [${line}]`)\n\n    createStdinLineHandler()\n      ->\n        stderr as Stderr\n        debugLevel as Integer\n      <-\n        processor as lineToCustomerRecord?\n\n      processor: (stderr, debugLevel) is lineToCustomerRecord as pure function\n        rtn: DictEntry() of (String, CustomerRecord)\n        traceLevel <- 3\n        expectedFieldCount <- 4\n\n        splitLine <- line.split(/,/)\n        if debugLevel == traceLevel\n          stderr.println(`About to split stdin line [${line}]`)\n\n        if length of splitLine == expectedFieldCount\n          id <- splitLine.getOrDefault(0, \"\").trim()\n          firstname <- splitLine.getOrDefault(1, \"\").trim()\n          lastname <- splitLine.getOrDefault(2, \"\").trim()\n          dobStr <- splitLine.getOrDefault(3, \"\").trim()\n          if id is not empty and firstname is not empty and lastname is not empty and dobStr is not empty\n            dob <- $getAsDateTime(id, false, dobStr)\n            if dob?\n              entryValue <- CustomerRecord(id: id, firstName: firstname, lastName: lastname, email: String(), dob: dob, lastPurchase: String())\n              if debugLevel == traceLevel\n                stderr.println(`Line [${line}] processed`)\n              rtn :=? DictEntry(id, entryValue)\n\n        if not rtn?\n          stderr.println(`Invalid line [${line}]`)\n\n    getAsDateTime() as pure\n      ->\n        id as String\n        throwException as Boolean\n        aDateInput as String //expecting YYYYMMDD\n      <-\n        rtn as DateTime: DateTime()\n\n      expectedDateParts <- 3\n      group <- aDateInput.group(/(\\d{4})(\\d{2})(\\d{2})/)\n      if length group == expectedDateParts\n        dateStr <- cat group | join with dashSeparated | collect as String\n        rtn :=? DateTime(Date(dateStr))\n      else if throwException\n        throw Exception(`Id [${id}] Invalid date [${aDateInput}]`, 2)\n      else\n        Stderr().println(`Id [${id}] Invalid date [${aDateInput}]`)\n\n    validEntry() as pure\n      -> entry as DictEntry of (String, CustomerRecord)\n      <- rtn as Boolean: entry?\n\n    dashSeparated() as pure\n      ->\n        firstPart String\n        secondPart String\n      <-\n        rtn as String: firstPart? and secondPart? <- `${firstPart}-${secondPart}` : String()\n\n    outputFormatSeparated() as pure\n      ->\n        firstPart String\n        secondPart String\n      <-\n        rtn as String: firstPart? and secondPart? <- `${firstPart}, ${secondPart}` : String()\n\n    setupSignalHandling()\n      ->\n        verboseMode as Boolean\n        debugLevel as Integer\n\n      terminationHandler <- (verboseMode, debugLevel) is SignalHandler as function\n        result: 1 //The error code to terminate with\n        if verboseMode or debugLevel > 0\n          Stderr().println(`Handled Terminal Signal [${signal}]`)\n\n      terminations <- Signals().register([\"HUP\", \"ABRT\"], terminationHandler)\n      if terminations not contains \"HUP\"\n        Stderr().println(\"HUP Signal not supported\")\n      if terminations not contains \"ABRT\"\n        Stderr().println(\"ABRT Signal not supported\")\n\n      debugHandler <- (verboseMode, debugLevel) is SignalHandler as function\n        maxDebugLevel <- 3\n        result: Integer() //Note the Integer is not set so process will not terminate\n        if signal == \"USR1\" and debugLevel < maxDebugLevel\n          debugLevel++\n        else if signal == \"USR2\" and debugLevel > 0\n          debugLevel--\n        if verboseMode or debugLevel > 0\n          Stderr().println(`Handled Info Signal [${signal}] Debug Level now [${debugLevel}]`)\n\n      debugs <- Signals().register([\"USR1\", \"USR2\"], debugHandler)\n      if debugs not contains \"USR1\"\n        Stderr().println(\"USR1 Signal not supported\")\n      if debugs not contains \"USR2\"\n        Stderr().println(\"USR2 Signal not supported\")\n\n    outputHeader()\n      ->\n        verboseMode as Boolean\n        debugLevel as Integer\n        stdout as Stdout\n\n      detailedDebugLevel <- 2\n      enGB <- Locale(\"en_GB\")\n      if verboseMode or debugLevel > detailedDebugLevel\n        Stderr().println(`About to create output header with locale ${enGB}`)\n\n      envVars <- EnvVars()\n      user <- envVars contains \"USER\" <- envVars.get(\"USER\") else envVars.get(\"USERNAME\")\n      dateTime <- enGB.mediumFormat(SystemClock().dateTime())\n\n      stdout.println(`#Created by ${user} on ${dateTime}`)\n      stdout.println(\"#id, firstName, lastName, emailAddress, dateOfBirth, dateLastPurchase\")\n\n    createCustomerRecordMerger()\n      ->\n        stderr as Stderr\n        debugLevel as Integer\n        namedFileContents as Dict of (String, CustomerRecord)\n      <-\n        merge as customerRecordMerger?\n\n      merge: (stderr, debugLevel, namedFileContents) is customerRecordMerger\n        traceLevel <- 3\n        rtn: String() //Output will be unset by default and there for not output\n        id <- entry.key()\n        if debugLevel == traceLevel\n          stderr.println(`Merging id [${id}]`)\n        if namedFileContents contains id\n          stdinEntry <- entry.value()\n          namedFileEntry <- namedFileContents.getOrDefault(id, CustomerRecord())\n          stdinEntry :~: namedFileEntry\n          rtn := $stdinEntry\n        else\n          stderr.println(`Not merging [${id}] as named file does not contain id`)\n\n  defines class\n\n    OptionsHandler\n\n      processCommandLine() as pure\n        -> arguments as List of String\n        <- options as Dict of (String, String)?\n\n        getopts <- setupGetOpt(\":\")\n        options :=? getopts.options(arguments)\n\n      private setupGetOpt() as pure\n        -> rqParam as String\n        <- getopts as GetOpt?\n\n        supportedOptions <- setupSupportedOptions(rqParam)\n        usage <- setupUsage()\n        getopts :=? GetOpt(rqParam, supportedOptions, usage)\n\n      private setupSupportedOptions() as pure\n        -> rqParam as String\n        <- rtn as Dict of (String, String)?\n\n        rtn :=? {\n          \"-v\": String(),\n          \"-f\": rqParam,\n          \"-d\": rqParam\n          }\n\n      private setupUsage() as pure\n        <- rtn as String?\n\n        desc <- \"Invalid option, only those list below are supported:\"\n        verbose <- \"-v, verbose\"\n        filename <- \"-f filename, use file of filename (mandatory option)\"\n        debug <- \"-d level, use of debugging\"\n        rtn :=? `${desc}\\n${verbose}\\n${filename}\\n${debug}`\n\n      processDebugLevel()\n        ->\n          verboseMode as Boolean\n          level as String\n        <-\n          rtn as Integer: 0 //default to zero\n\n        maxDebugLevel <- 3\n        debugLevel <- Integer(level)\n\n        rtn := (debugLevel in 0 ... maxDebugLevel) <- debugLevel else 0\n\n        if verboseMode and (debugLevel not in 0 ... maxDebugLevel)\n          Stderr().println(`Debug level ${debugLevel} not supported - reverting to debug level '0'`)\n\n    NamedFileProcessor\n      verboseMode as Boolean: false\n      debugLevel as Integer: Integer()\n\n      NamedFileProcessor()\n        ->\n          verboseMode as Boolean\n          debugLevel as Integer\n        this.verboseMode = verboseMode\n        this.debugLevel = debugLevel\n\n      processNamedFile()\n        -> filename as Optional of String\n        <- rtn <- Dict() of (String, CustomerRecord)\n\n        stderr <- Stderr()\n        if filename?\n          namedFile <- getNamedFile(filename.get())\n          validLine <- createLineValidator(stderr, debugLevel)\n          toEntry <- createNamedFileLineHandler(stderr, debugLevel)\n\n          if verboseMode or debugLevel > 0\n            stderr.println(`About to start processing [${namedFile}]`)\n\n          cat namedFile.input() | filter by validLine | map toEntry > rtn\n\n          if debugLevel > 1\n            stderr.println(`Processing [${namedFile}] complete`)\n        else\n          throw Exception(\"Filename of 'named file' is required\", 2)\n\n      private getNamedFile()\n        -> filename as String\n        <- rtn as TextFile: TextFile()\n\n        filePath <- FileSystemPath(filename)\n        rtn := filePath.isAbsolute() <- TextFile(filePath) else TextFile(FileSystem().cwd() + filePath)\n        if not rtn?\n          throw Exception(`${filePath} is not an existing file`, 2)\n        if not rtn.isReadable()\n          throw Exception(`${rtn} is not readable`, 2)\n\n      private createNamedFileLineHandler() as pure\n        ->\n          stderr as Stderr\n          debugLevel as Integer\n        <-\n          processor as lineToCustomerRecord?\n\n        processor :=? (stderr, debugLevel) is lineToCustomerRecord as pure function\n          traceLevel <- 3\n          expectedFieldCount <- 4\n          splitLine <- line.split(/:/)\n          if debugLevel == traceLevel\n            stderr.println(`About to split line [${line}]`)\n\n          if length of splitLine != expectedFieldCount\n            throw Exception(`Invalid line [${line}]`, 2)\n          id <- splitLine.getOrDefault(0, \"\").trim()\n          if id is empty\n            throw Exception(`Invalid line [${line}] empty ID`, 2)\n\n          emailAddress <- splitLine.getOrDefault(1, \"\").trim()\n          if emailAddress not matches /[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$/\n            throw Exception(`Id [${id}] Invalid email address [${emailAddress}]`, 2)\n\n          dateLastPurchase <- $getAsDateTime(id, true, splitLine.getOrDefault(3, \"\").trim())\n\n          entryValue <- CustomerRecord(id: id, firstName: String(), lastName: String(), email: emailAddress, dob: String(), lastPurchase: dateLastPurchase)\n          if debugLevel == traceLevel\n            stderr.println(`Named file line [${line}] processed`)\n\n          rtn :=? DictEntry(id, entryValue)\n\n      default operator ?\n\n  defines record\n\n    CustomerRecord\n      id <- String()\n      firstName <- String()\n      lastName <- String()\n      email <- String()\n      dob <- String()\n      lastPurchase <- String()\n\n      default CustomerRecord() as pure\n\n      CustomerRecord() as pure\n        ->\n          id as String\n          firstName as String\n          lastName as String\n          email as String\n          dob as String\n          lastPurchase as String\n        this.id :=? String(id)\n        this.firstName :=? String(firstName)\n        this.lastName :=? String(lastName)\n        this.email :=? String(email)\n        this.dob :=? String(dob)\n        this.lastPurchase :=? String(lastPurchase)\n\n      override operator ? as pure\n        <- rtn as Boolean: id?\n\n      operator :~:\n        -> other as CustomerRecord\n\n        id :=? String(other.id)\n        firstName :=? String(other.firstName)\n        lastName :=? String(other.lastName)\n        email :=? String(other.email)\n        dob :=? String(other.dob)\n        lastPurchase :=? String(other.lastPurchase)\n\n      operator $ as pure\n        <- rtn as String: cat [id, firstName, lastName, email, dob, lastPurchase]\n          | join with outputFormatSeparated\n          | collect as String","expectedOutput":null,"kind":"bad","errors":["E11021"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"standardTypes/standardTypes_mutex_lock.ek9","url":"https://ek9.io/examples/standardTypes/standardTypes_mutex_lock.html","title":"A MutexLock owned by a class, used through its methods","code":"#!ek9\ndefines module site.standardTypes.mutexLock\n\n  defines class\n\n    <?-\n      MutexLock lives as a field on this class — the canonical field-rooted-home\n      pattern that EK9 requires for compile-time lock identity tracking. Methods\n      on the class expose nameHolder operations; the lock itself is never handed\n      out as a local or a return value.\n    -?>\n    ProtectedName\n      lockedName as MutexLock of String: MutexLock(\"Steve\")\n\n      <?-\n        Read the nameHolder value by copying it out via :=:\n      -?>\n      read()\n        <- rtn as String?\n\n        rtn: String()\n\n        accessKey <- (rtn) is MutexKey of String as function\n          rtn :=: lockedItem\n\n        require lockedName.enter(accessKey)\n\n      <?-\n        Update the nameHolder value by copying the new value in via :=:\n        Note: :=: (copy), not := (reassignment) — reassignment would\n        leave an outside reference to the original value, bypassing the lock.\n      -?>\n      update()\n        -> newName as String\n\n        accessKey <- (newName) is MutexKey of String as function\n          lockedItem :=: newName\n\n        require lockedName.enter(accessKey)\n\n      <?-\n        Non-blocking update — returns false if the lock was held by\n        another thread; the caller can decide whether to retry.\n      -?>\n      tryUpdate()\n        -> newName as String\n        <- updated as Boolean: Boolean()\n\n        accessKey <- (newName) is MutexKey of String as function\n          lockedItem :=: newName\n\n        updated: lockedName.tryEnter(accessKey)\n\n      default operator ?\n\n  defines program\n\n    LockExample()\n      stdout <- Stdout()\n\n      //Construct the nameHolder wrapper — the MutexLock is created\n      //by the class's field initialiser, not here in user code.\n      nameHolder <- ProtectedName()\n\n      stdout.println(`Initial: [${nameHolder.read()}]`)\n\n      //Blocking update via the class's API.\n      nameHolder.update(\"Stephen\")\n      stdout.println(`After blocking update: [${nameHolder.read()}]`)\n\n      //Non-blocking update — the Boolean tells us whether the lock was free.\n      success <- nameHolder.tryUpdate(\"Stevie\")\n      stdout.println(`Non-blocking update succeeded? ${success}: [${nameHolder.read()}]`)","expectedOutput":"Initial: [Steve]\nAfter blocking update: [Stephen]\nNon-blocking update succeeded? true: [Stevie]\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"standardTypes/standardTypes_record_string.ek9","url":"https://ek9.io/examples/standardTypes/standardTypes_record_string.html","title":"A record's string conversion by interpolation","code":"#!ek9\ndefines module site.standardtypes.recordstring\n\n  defines record\n\n    CustomerRecord\n      id <- String()\n      firstName <- String()\n      lastName <- String()\n      email <- String()\n      dob <- String()\n      lastPurchase <- String()\n\n      default CustomerRecord() as pure\n\n      CustomerRecord() as pure\n        ->\n          id as String\n          firstName as String\n          lastName as String\n          email as String\n          dob as String\n          lastPurchase as String\n        this.id :=? String(id)\n        this.firstName :=? String(firstName)\n        this.lastName :=? String(lastName)\n        this.email :=? String(email)\n        this.dob :=? String(dob)\n        this.lastPurchase :=? String(lastPurchase)\n\n      override operator ? as pure\n        <- rtn as Boolean: id?\n\n      operator $ as pure\n        <- rtn as String: String()\n        rtn := `${id}, ${firstName}, ${lastName}, ${email}, ${dob}, ${lastPurchase}`\n\n  defines program\n\n    RecordString()\n      stdout <- Stdout()\n      customer <- CustomerRecord(id: \"1\", firstName: \"Steve\", lastName: \"Limb\", email: \"a@b.com\", dob: \"1960-01-01\", lastPurchase: \"2020-01-01\")\n      stdout.println($customer)","expectedOutput":"1, Steve, Limb, a@b.com, 1960-01-01, 2020-01-01\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"standardTypes/standardTypes_security.ek9","url":"https://ek9.io/examples/standardTypes/standardTypes_security.html","title":"InputSanitizer, Sensitive and the Privileged trait","code":"#!ek9\ndefines module site.standardTypes.security\n\n  defines function\n\n    processData()\n      -> cleaned as String\n      Stdout().println(`Processing ${cleaned}`)\n\n  defines class\n\n    DatabaseDriver with trait of Privileged\n\n      connect()\n        ->\n          host as String\n          port as Integer\n          user as String\n          password as Sensitive\n        //reveal() is legal here - DatabaseDriver has the Privileged trait\n        rawPassword <- password.reveal()\n        internalConnect(host: host, port: port, user: user, secret: rawPassword)\n\n      private internalConnect()\n        ->\n          host as String\n          port as Integer\n          user as String\n          secret as String\n        Stdout().println(`Connecting ${user}@${host}:${port} with a ${length secret} character secret`)\n\n      default operator ?\n\n  defines program\n\n    SanitizerDemo()\n      userInput <- \"Some user supplied text\"\n      sanitizer <- InputSanitizer()\n\n      //Sanitize input - returns unset if threat detected\n      result <- sanitizer.sanitize(userInput)\n      if result?\n        processData(result)\n\n      //With context for richer logging\n      context <- SanitizationContext(\n        timestamp: SystemClock().dateTime(),\n        service: \"UserService\",\n        operation: \"getUser\",\n        fieldName: \"userId\",\n        fieldSource: \"PATH\",\n        sourceIp: \"127.0.0.1\",\n        traceId: \"trace-0001\"\n        )\n      richResult <- sanitizer.sanitize(userInput, context)\n      if richResult?\n        processData(richResult)\n\n    SensitiveDemo()\n      stdout <- Stdout()\n      database <- DatabaseDriver()\n      envVars <- EnvVars()\n\n      //Load secret from environment variable\n      if dbPassword <- envVars.sensitiveGet(\"DB_PASSWORD\")\n        //dbPassword is set, pass to database driver\n        database.connect(host: \"localhost\", port: 5432, user: \"app\", password: dbPassword)\n\n        //This prints \"***REDACTED***\" - never the real password\n        stdout.println($dbPassword)\n      else\n        stdout.println(\"DB_PASSWORD is not set, so there is nothing to connect with\")","expectedOutput":{"SanitizerDemo":"Processing Some user supplied text\nProcessing Some user supplied text\n","SensitiveDemo":"DB_PASSWORD is not set, so there is nothing to connect with\n"},"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"standardTypes/standardTypes_seeded_random.ek9","url":"https://ek9.io/examples/standardTypes/standardTypes_seeded_random.html","title":"A seeded random sequence that repeats on every run","code":"#!ek9\ndefines module site.standardTypes.seededRandom\n\n  defines program\n\n    SeededRandomExample()\n      stdout <- Stdout()\n\n      //Same seed -> same sequence every run, so output is reproducible\n      rnd <- SeededRandom(42)\n\n      dice1 <- rnd.next(1, 6)\n      dice2 <- rnd.next(1, 6)\n      stdout.println(`Rolled ${dice1} and ${dice2}`)","expectedOutput":"Rolled 2 and 5\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"streamsAndPipelines/streamsAndPipelines_exceptions.ek9","url":"https://ek9.io/examples/streamsAndPipelines/streamsAndPipelines_exceptions.html","title":"An Exception thrown inside a pipeline stage","code":"#!ek9\ndefines module site.streamsAndPipelines.exceptions\n\n  defines function\n\n    parsePrice()\n      -> text as String\n      <- rtn as Integer: Integer(text)\n      if not rtn?\n        throw Exception(`Not a price: ${text}`, 3)\n\n    parsePriceOrZero()\n      -> text as String\n      <- rtn as Integer: 0\n      try\n        rtn: parsePrice(text)\n      catch\n        -> ex as Exception\n        Stdout().println(`skipped: ${ex.reason()}`)\n\n  defines program\n\n    PipelineExceptionDemo()\n      stdout <- Stdout()\n      prices <- [\"12\", \"oops\", \"30\", \"45\"]\n\n      try\n        total <- cat prices | map with parsePrice | collect as List of Integer\n        stdout.println(`unreachable: ${total}`)\n      catch\n        -> ex as Exception\n        stdout.println(`pipeline stopped: ${ex.reason()}`)\n\n      recovered <- cat prices | map with parsePriceOrZero | collect as List of Integer\n      stdout.println(`recovered: ${recovered}`)","expectedOutput":"pipeline stopped: Not a price: oops\nskipped: Not a price: oops\nrecovered: [12, 0, 30, 45]\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"streamsAndPipelines/streamsAndPipelines_library.ek9","url":"https://ek9.io/examples/streamsAndPipelines/streamsAndPipelines_library.html","title":"A library of books processed through stream pipelines","code":"#!ek9\ndefines module site.streamsAndPipelines.library\n\n  defines constant\n    MINIMUM_BOOKS <- 3\n    SENIOR_AGE <- 50\n\n  defines type\n\n    AuthorId as Integer constrain\n      > 0\n\n    Age as Integer constrain\n      > 0\n\n    Name as String constrain as\n      matches /^[a-zA-Z -]+$/\n\n    BookTitle as String constrain as\n      matches /^[a-zA-Z0-9 -+]+$/\n\n    <?-\n      Simple enumeration for controlling filtering\n    -?>\n    BookFilterSelection\n      SkipTwo\n      JustFirst\n      JustLast\n\n  defines class\n\n    <?-\n      Models the author of books.\n    -?>\n    Author\n      id as AuthorId?\n      age as Age?\n      firstname as Name?\n      surname as Name?\n\n      Author() as pure\n        ->\n          id as AuthorId\n          age as Age\n          firstname as Name\n          surname as Name\n        require id? and age? and firstname? and surname?\n        this.id:=? AuthorId(id)\n        this.age:=? Age(age)\n        this.firstname:=? Name(firstname)\n        this.surname:=? Name(surname)\n\n      Author() as pure\n        -> author as Author\n        this(id: author.id(), age: author.age(), firstname: author.firstname(), surname: author.surname())\n\n      <?-\n        Stop creation of empty Author.\n      -?>\n      default private Author() as pure\n\n      id() as pure\n        <- rtn as AuthorId: id\n\n      age() as pure\n        <- rtn as Age: age\n\n      firstname() as pure\n        <- rtn as Name: firstname\n\n      surname() as pure\n        <- rtn as Name: surname\n\n      operator == as pure\n        -> author as Author\n        <- rtn as Boolean: id == author.id()\n\n      operator #? as pure\n        <- rtn as Integer: #?id\n\n      operator $ as pure\n        <- rtn as String: `Author: ${firstname} ${surname}, Age: ${age}`\n\n      override operator ? as pure\n        <- rtn as Boolean: age? and firstname? and surname?\n\n      operator :=:\n        -> author as Author\n        id :=: author.id()\n        age :=: author.age()\n        firstname :=: author.firstname()\n        surname :=: author.surname()\n\n    Book\n      title as BookTitle?\n      author as Author?\n      published as Date?\n\n      Book() as pure\n        ->\n          title as BookTitle\n          author as Author\n          published as Date\n        require title? and author? and published?\n        this.title:=? BookTitle(title)\n        this.author:=? Author(author)\n        this.published:=? Date(published)\n\n      <?-\n        Stop creation of empty Book.\n      -?>\n      default private Book() as pure\n\n      author() as pure\n        <- rtn as Author: author\n\n      published() as pure\n        <- rtn as Date: published\n\n      operator $ as pure\n        <- rtn as String: `Title: ${title}, ${author}, Published: ${published}`\n\n      operator #? as pure\n        <- rtn as Integer: #? $this\n\n      operator #^ as pure\n        <- rtn as String: $this\n\n      operator <=> as pure\n        -> book as Book\n        <- rtn as Integer: published() <=> book.published()\n\n      override operator ? as pure\n        <- rtn as Boolean: title? and author? and published?\n\n    <?-\n      Model the concept of a library, just an in-memory map for now\n    -?>\n    Library\n      books as List of Book?\n\n      Library() as pure\n        -> withBooks as List of Book\n        books :=? withBooks\n\n      Library() as pure\n        this([\n          Book(BookTitle(\"Java\"), Author(id: AuthorId(1), age: Age(50), firstname: Name(\"John\"), surname: Name(\"Doe\")), 1998-01-01),\n          Book(BookTitle(\"C++\"), Author(id: AuthorId(1), age: Age(42), firstname: Name(\"John\"), surname: Name(\"Doe\")), 1990-01-07),\n          Book(BookTitle(\"Scala\"), Author(id: AuthorId(1), age: Age(67), firstname: Name(\"John\"), surname: Name(\"Doe\")), 2015-03-02),\n          Book(BookTitle(\"Python\"), Author(id: AuthorId(1), age: Age(62), firstname: Name(\"John\"), surname: Name(\"Doe\")), 2010-12-02),\n          Book(BookTitle(\"HTML\"), Author(id: AuthorId(2), age: Age(58), firstname: Name(\"Mark\"), surname: Name(\"Pickford\")), 2008-07-02),\n          Book(BookTitle(\"CSS\"), Author(id: AuthorId(4), age: Age(51), firstname: Name(\"Mark\"), surname: Name(\"Keely\")), 2008-04-02),\n          Book(BookTitle(\"ADA\"), Author(id: AuthorId(5), age: Age(44), firstname: Name(\"Ada\"), surname: Name(\"Lovelace\")), 1988-01-02),\n          Book(BookTitle(\"Dart\"), Author(id: AuthorId(6), age: Age(47), firstname: Name(\"Peter\"), surname: Name(\"Dove\")), 2020-01-02),\n          Book(BookTitle(\"C#\"), Author(id: AuthorId(7), age: Age(60), firstname: Name(\"William\"), surname: Name(\"Fence\")), 2012-10-02),\n          Book(BookTitle(\"Javascript\"), Author(id: AuthorId(3), age: Age(52), firstname: Name(\"James\"), surname: Name(\"Pickford\")), 2008-03-02),\n          Book(BookTitle(\"C\"), Author(id: AuthorId(1), age: Age(42), firstname: Name(\"John\"), surname: Name(\"Doe\")), 1990-01-07),\n          Book(BookTitle(\"C++\"), Author(id: AuthorId(7), age: Age(38), firstname: Name(\"William\"), surname: Name(\"Fence\")), 1990-04-02),\n          Book(BookTitle(\"C\"), Author(id: AuthorId(7), age: Age(38), firstname: Name(\"William\"), surname: Name(\"Fence\")), 1990-04-14),\n          Book(BookTitle(\"Haskell\"), Author(id: AuthorId(7), age: Age(30), firstname: Name(\"William\"), surname: Name(\"Fence\")), 1982-04-14),\n          Book(BookTitle(\"Lisp\"), Author(id: AuthorId(7), age: Age(25), firstname: Name(\"William\"), surname: Name(\"Fence\")), 1977-09-24)\n          ])\n\n      <?-\n        While you would never really 'iterate' through all the books in a library - this\n        just enables the demonstration of streaming.\n        Clearly you would normally have multiple maps/indexes etc to locate books via a search\n        mechanism.\n      -?>\n      iterator() as pure\n        <- rtn as Iterator of Book: books.iterator()\n\n      operator + as pure\n        -> book as Book\n        <- rtn as Library: Library(books + book)\n\n      override operator ? as pure\n        <- rtn as Boolean: books?\n\n  defines program\n\n    <?-\n      Just send all the books in the library out to stdout.\n      Because Library has an iterator method 'cat' will use it to get each book.\n    -?>\n    JustCatBooks()\n      stdout <- Stdout()\n      library <- Library()\n\n      cat library > stdout\n\n  defines function\n\n    comparingAuthor() as pure\n      ->\n        book1 as Book\n        book2 as Book\n      <-\n        rtn as Integer: book1.author().id() <=> book2.author().id()\n\n  defines program\n\n    <?-\n      Now sort the books before outputting.\n      This uses a specific comparator.\n    -?>\n    SortBooksByAuthor()\n      stdout <- Stdout()\n      library <- Library()\n\n      cat library | sort by comparingAuthor > stdout\n\n  defines function\n\n    dateBookPublished() as pure\n      -> book as Book\n      <- rtn as Date: book.published()\n\n    comparingAuthorThenDate() as pure\n      ->\n        book1 as Book\n        book2 as Book\n      <-\n        rtn as Integer: comparingAuthor(book1, book2)\n      if rtn == 0\n        rtn: book1 <=> book2\n\n  defines program\n\n    <?-\n      Example of grouping books by the same author that were published on the same date.\n      'group' only joins ADJACENT books whose keys are equal, so the books are first sorted by\n      author and then by published date; each run of equal dates then becomes one group.\n      The groups are output in the order they were created, each as a List of Book on its own line.\n    -?>\n    GroupBooksByPublishedDate()\n      stdout <- Stdout()\n      library <- Library()\n      cat library | sort by comparingAuthorThenDate | group by dateBookPublished > stdout\n\n  defines function\n\n    compareDatePublished() as pure\n      ->\n        book1 as Book\n        book2 as Book\n      <-\n        rtn as Integer: book1.published() <=> book2.published()\n\n    orderOnPublishedDate() as pure\n      -> books as List of Book\n      <- rtn as List of Book: cat books | sort by compareDatePublished | collect as List of Book\n\n  defines program\n\n    <?-\n      This example outputs the books in author order, but also for each of those authors sorts their\n      books by published date.\n    -?>\n    ProcessByAuthor()\n      stdout <- Stdout()\n      library <- Library()\n\n      //This is the nearest ek9 gets to a lambda - it's a bit 'wordy'.\n      //In effect we are creating a function delegate that is a 'Function' that accepts a 'Book' and\n      //returns an 'AuthorId' type. It is pure in nature - it does not mutate the book in anyway.\n      //The arguments of the 'Function' inferred from its definition and so can just be used in the parenthesis.\n\n      authorId <- () is Function of (Book, AuthorId) as pure function (r:=? t.author().id())\n\n      cat library\n        | sort by comparingAuthor\n        | group by authorId\n        | map by orderOnPublishedDate\n        | flatten\n        > stdout\n\n  defines function\n\n    sufficientBooks() as pure\n      -> books as List of Book\n      <- rtn as Boolean: length books >= MINIMUM_BOOKS\n\n  defines program\n    <?-\n      This example shows two things, firstly it inlines the dynamic function (not keen on this but it can be done).\n      Then it filters the lists that do not have sufficient books (in this case three or more).\n      Only then does it order those books on their published date.\n    -?>\n    ProcessByAuthorWithThreeOrMoreBooks()\n      stdout <- Stdout()\n      library <- Library()\n\n      cat library\n        | sort by comparingAuthor\n        | group by () is Function of (Book, AuthorId) as pure function (r:=? t.author().id())\n        | filter with sufficientBooks\n        | map by orderOnPublishedDate\n        | flatten\n        > stdout\n\n  defines program\n\n    <?-\n      Similar to the other examples, but this one just skips the first two books by\n      each author (if they have 3 or more books).\n      Note, there is a sort of common pattern to these, if an intermediate operation needs\n      a function, you can either define a basic function or just create a dynamic function.\n    -?>\n    ProcessByAuthorWithThreeOrMoreBooksIgnoreFirstTwo()\n      stdout <- Stdout()\n      library <- Library()\n\n      authorId <- () is Function of (Book, AuthorId) as pure function (r:=? t.author().id())\n      excludingFirstTwoBooks <- () is Function of(List of Book, List of Book) as pure function\n        r:=? cat t | skip 2 | collect as List of Book\n\n      cat library\n        | sort by comparingAuthor\n        | group by authorId\n        | filter with sufficientBooks\n        | map by orderOnPublishedDate\n        | map by excludingFirstTwoBooks\n        | flatten\n        > stdout\n\n  defines function\n\n    bookFilter() as pure abstract\n      -> books as List of Book\n      <- filtered as List of Book?\n\n    <?-\n      Example of a higher order function and dynamic functions.\n      There are other ways to solve the mapping of an enumerations requirement to a function.\n      This uses a switch/given expression in a pure context\n    -?>\n    suitableBookFilter() as pure\n      -> selection as BookFilterSelection\n      <- rtn as bookFilter: given selection\n        <- theFilter as bookFilter?\n        when BookFilterSelection.SkipTwo\n          theFilter:=? () is bookFilter as pure function (filtered:=? cat books | skip 2 | collect as List of Book)\n        when BookFilterSelection.JustFirst\n          theFilter:=? () is bookFilter as pure function (filtered:=? cat books | head 1 | collect as List of Book)\n        when BookFilterSelection.JustLast\n          theFilter:=? () is bookFilter as pure function (filtered:=? cat books | tail 1 | collect as List of Book)\n        default\n          theFilter:=? () is bookFilter as pure function (filtered:=? books)\n\n  defines program\n\n    <?-\n      Example of using a higher order function to create the book filter.\n    -?>\n    ProcessByAuthorUsingHigherOrderFunction()\n      stdout <- Stdout()\n      library <- Library()\n      authorId <- () is Function of (Book, AuthorId) as pure function (r:=? t.author().id())\n\n      stdout.println(\"Omit first two books where author has three or more books\")\n      cat library\n        | sort by comparingAuthor\n        | group by authorId\n        | filter with sufficientBooks\n        | map by orderOnPublishedDate\n        | map with suitableBookFilter(BookFilterSelection.SkipTwo)\n        | flatten\n        > stdout\n\n  defines function\n\n    filterBooksToOutput()\n      ->\n        library as Library\n        filterSelection as BookFilterSelection\n        output as StringOutput\n\n      authorId <- () is Function of (Book, AuthorId) as pure function (r:=? t.author().id())\n\n      cat library\n        | sort by comparingAuthor\n        | group by authorId\n        | filter with sufficientBooks\n        | map by orderOnPublishedDate\n        | map with suitableBookFilter(filterSelection)\n        | flatten\n        > output\n\n  defines program\n\n    <?-\n      Next logical step is to extract the above and put it into a function called 'filterBooksToOutput'\n      Then it can just be called with appropriate parameters.\n    -?>\n    ProcessByAuthorUsingParameterisedFunction()\n      stdout <- Stdout()\n      library <- Library()\n\n      stdout.println(\"Omit first two books where author has three or more books\")\n      filterBooksToOutput(library, BookFilterSelection.SkipTwo, stdout)\n\n      stdout.println(\"First book where author has three or more books\")\n      filterBooksToOutput(library, BookFilterSelection.JustFirst, stdout)\n\n      stdout.println(\"Last book where author has three or more books\")\n      filterBooksToOutput(library, BookFilterSelection.JustLast, stdout)\n\n  defines function\n\n    bookSigningEvent() as pure\n      -> book as Book\n      <- rtn as String: `Date: ${book.published()}`\n\n  defines program\n\n    UniquePublishingDatesFromAuthorWithThreeOrMoreBooks()\n      stdout <- Stdout()\n      library <- Library()\n      authorId <- () is Function of (Book, AuthorId) as pure function (r:=? t.author().id())\n\n      authorsBooks as List of Book: List()\n\n      booksByEachAuthor as List of List of Book: List()\n\n      stdout.println(\"Unique signing events on day of publication by authors with three or more books.\")\n\n      cat library\n        | sort by comparingAuthor\n        | group by authorId\n        | tee in booksByEachAuthor\n        | filter by sufficientBooks\n        | map by orderOnPublishedDate\n        | flatten\n        | tee in authorsBooks\n        | uniq by dateBookPublished\n        | sort by compareDatePublished\n        | map with bookSigningEvent\n        > stdout\n\n      stdout.println(\"Books From author with three or more books\")\n      cat authorsBooks > stdout\n\n      stdout.println(`There are ${length booksByEachAuthor} authors in total with any number of books`)\n\n  defines function\n\n    bookAuthor() as pure\n      -> book as Book\n      <- author as Author: book.author()\n\n    acceptableAuthorAge() as pure\n      -> author as Author\n      <- rtn as Boolean: author.age() >= Age(50)\n\n    authorName() as pure\n      -> author as Author\n      <- rtn as String: `${author.firstname()} ${author.surname()}`\n\n    comparingAuthorName() as pure\n      ->\n        author1 as Author\n        author2 as Author\n      <-\n        rtn as Integer: author1.surname() <=> author2.surname()\n      if rtn == 0\n        rtn: author1.firstname() <=> author2.firstname()\n\n  defines program\n\n    LibraryExample()\n      stdout <- Stdout()\n      library <- Library()\n\n      cat library\n        | map with bookAuthor\n        | filter by acceptableAuthorAge\n        | uniq\n        | sort by comparingAuthorName\n        | map with authorName\n        > stdout\n\n  defines function\n\n    isModernBook() as pure\n      -> book as Book\n      <- rtn as Boolean: book.published() >= 2000-01-01\n\n    firstBookOnly() as pure\n      -> books as List of Book\n      <- rtn as List of Book: cat books | head 1 | collect as List of Book\n\n  defines program\n\n    <?-\n      Split books by publication date: every modern book (published 2000 or later)\n      starts a new group, then take just the first book from each group.\n    -?>\n    SplitBooksByEra()\n      stdout <- Stdout()\n      library <- Library()\n\n      stdout.println(\"First book from each group, a new group starting at each modern book\")\n\n      cat library\n        | sort by compareDatePublished\n        | split with isModernBook\n        | map by firstBookOnly\n        | flatten\n        > stdout\n\n    <?-\n      To get exactly two eras, group by era instead: once sorted by date the\n      pre-2000 books and the modern books are each one run of equal keys.\n    -?>\n    GroupBooksByEra()\n      stdout <- Stdout()\n      library <- Library()\n\n      stdout.println(\"First book from each era (pre-2000 and 2000+)\")\n\n      cat library\n        | sort by compareDatePublished\n        | group by isModernBook\n        | map by firstBookOnly\n        | flatten\n        > stdout\n\n  defines program\n    ImperativeLibraryExample()\n      stdout <- Stdout()\n      library <- Library()\n\n      uniqueAuthors as Dict of (AuthorId, Author): Dict()\n\n      for book in library\n        author <- book.author()\n        if author.age() >= SENIOR_AGE\n          if uniqueAuthors not contains author.id()\n            uniqueAuthors += DictEntry(author.id(), author)\n\n      for author in uniqueAuthors.values()\n        stdout.println(`${author.firstname()} ${author.surname()}`)","expectedOutput":{"JustCatBooks":"Title: Java, Author: John Doe, Age: 50, Published: 1998-01-01\nTitle: C++, Author: John Doe, Age: 42, Published: 1990-01-07\nTitle: Scala, Author: John Doe, Age: 67, Published: 2015-03-02\nTitle: Python, Author: John Doe, Age: 62, Published: 2010-12-02\nTitle: HTML, Author: Mark Pickford, Age: 58, Published: 2008-07-02\nTitle: CSS, Author: Mark Keely, Age: 51, Published: 2008-04-02\nTitle: ADA, Author: Ada Lovelace, Age: 44, Published: 1988-01-02\nTitle: Dart, Author: Peter Dove, Age: 47, Published: 2020-01-02\nTitle: C#, Author: William Fence, Age: 60, Published: 2012-10-02\nTitle: Javascript, Author: James Pickford, Age: 52, Published: 2008-03-02\nTitle: C, Author: John Doe, Age: 42, Published: 1990-01-07\nTitle: C++, Author: William Fence, Age: 38, Published: 1990-04-02\nTitle: C, Author: William Fence, Age: 38, Published: 1990-04-14\nTitle: Haskell, Author: William Fence, Age: 30, Published: 1982-04-14\nTitle: Lisp, Author: William Fence, Age: 25, Published: 1977-09-24\n","SortBooksByAuthor":"Title: Java, Author: John Doe, Age: 50, Published: 1998-01-01\nTitle: C++, Author: John Doe, Age: 42, Published: 1990-01-07\nTitle: Scala, Author: John Doe, Age: 67, Published: 2015-03-02\nTitle: Python, Author: John Doe, Age: 62, Published: 2010-12-02\nTitle: C, Author: John Doe, Age: 42, Published: 1990-01-07\nTitle: HTML, Author: Mark Pickford, Age: 58, Published: 2008-07-02\nTitle: Javascript, Author: James Pickford, Age: 52, Published: 2008-03-02\nTitle: CSS, Author: Mark Keely, Age: 51, Published: 2008-04-02\nTitle: ADA, Author: Ada Lovelace, Age: 44, Published: 1988-01-02\nTitle: Dart, Author: Peter Dove, Age: 47, Published: 2020-01-02\nTitle: C#, Author: William Fence, Age: 60, Published: 2012-10-02\nTitle: C++, Author: William Fence, Age: 38, Published: 1990-04-02\nTitle: C, Author: William Fence, Age: 38, Published: 1990-04-14\nTitle: Haskell, Author: William Fence, Age: 30, Published: 1982-04-14\nTitle: Lisp, Author: William Fence, Age: 25, Published: 1977-09-24\n","GroupBooksByPublishedDate":"[Title: C++, Author: John Doe, Age: 42, Published: 1990-01-07, Title: C, Author: John Doe, Age: 42, Published: 1990-01-07]\n[Title: Java, Author: John Doe, Age: 50, Published: 1998-01-01]\n[Title: Python, Author: John Doe, Age: 62, Published: 2010-12-02]\n[Title: Scala, Author: John Doe, Age: 67, Published: 2015-03-02]\n[Title: HTML, Author: Mark Pickford, Age: 58, Published: 2008-07-02]\n[Title: Javascript, Author: James Pickford, Age: 52, Published: 2008-03-02]\n[Title: CSS, Author: Mark Keely, Age: 51, Published: 2008-04-02]\n[Title: ADA, Author: Ada Lovelace, Age: 44, Published: 1988-01-02]\n[Title: Dart, Author: Peter Dove, Age: 47, Published: 2020-01-02]\n[Title: Lisp, Author: William Fence, Age: 25, Published: 1977-09-24]\n[Title: Haskell, Author: William Fence, Age: 30, Published: 1982-04-14]\n[Title: C++, Author: William Fence, Age: 38, Published: 1990-04-02]\n[Title: C, Author: William Fence, Age: 38, Published: 1990-04-14]\n[Title: C#, Author: William Fence, Age: 60, Published: 2012-10-02]\n","ProcessByAuthor":"Title: C++, Author: John Doe, Age: 42, Published: 1990-01-07\nTitle: C, Author: John Doe, Age: 42, Published: 1990-01-07\nTitle: Java, Author: John Doe, Age: 50, Published: 1998-01-01\nTitle: Python, Author: John Doe, Age: 62, Published: 2010-12-02\nTitle: Scala, Author: John Doe, Age: 67, Published: 2015-03-02\nTitle: HTML, Author: Mark Pickford, Age: 58, Published: 2008-07-02\nTitle: Javascript, Author: James Pickford, Age: 52, Published: 2008-03-02\nTitle: CSS, Author: Mark Keely, Age: 51, Published: 2008-04-02\nTitle: ADA, Author: Ada Lovelace, Age: 44, Published: 1988-01-02\nTitle: Dart, Author: Peter Dove, Age: 47, Published: 2020-01-02\nTitle: Lisp, Author: William Fence, Age: 25, Published: 1977-09-24\nTitle: Haskell, Author: William Fence, Age: 30, Published: 1982-04-14\nTitle: C++, Author: William Fence, Age: 38, Published: 1990-04-02\nTitle: C, Author: William Fence, Age: 38, Published: 1990-04-14\nTitle: C#, Author: William Fence, Age: 60, Published: 2012-10-02\n","ProcessByAuthorWithThreeOrMoreBooks":"Title: C++, Author: John Doe, Age: 42, Published: 1990-01-07\nTitle: C, Author: John Doe, Age: 42, Published: 1990-01-07\nTitle: Java, Author: John Doe, Age: 50, Published: 1998-01-01\nTitle: Python, Author: John Doe, Age: 62, Published: 2010-12-02\nTitle: Scala, Author: John Doe, Age: 67, Published: 2015-03-02\nTitle: Lisp, Author: William Fence, Age: 25, Published: 1977-09-24\nTitle: Haskell, Author: William Fence, Age: 30, Published: 1982-04-14\nTitle: C++, Author: William Fence, Age: 38, Published: 1990-04-02\nTitle: C, Author: William Fence, Age: 38, Published: 1990-04-14\nTitle: C#, Author: William Fence, Age: 60, Published: 2012-10-02\n","ProcessByAuthorWithThreeOrMoreBooksIgnoreFirstTwo":"Title: Java, Author: John Doe, Age: 50, Published: 1998-01-01\nTitle: Python, Author: John Doe, Age: 62, Published: 2010-12-02\nTitle: Scala, Author: John Doe, Age: 67, Published: 2015-03-02\nTitle: C++, Author: William Fence, Age: 38, Published: 1990-04-02\nTitle: C, Author: William Fence, Age: 38, Published: 1990-04-14\nTitle: C#, Author: William Fence, Age: 60, Published: 2012-10-02\n","ProcessByAuthorUsingHigherOrderFunction":"Omit first two books where author has three or more books\nTitle: Java, Author: John Doe, Age: 50, Published: 1998-01-01\nTitle: Python, Author: John Doe, Age: 62, Published: 2010-12-02\nTitle: Scala, Author: John Doe, Age: 67, Published: 2015-03-02\nTitle: C++, Author: William Fence, Age: 38, Published: 1990-04-02\nTitle: C, Author: William Fence, Age: 38, Published: 1990-04-14\nTitle: C#, Author: William Fence, Age: 60, Published: 2012-10-02\n","ProcessByAuthorUsingParameterisedFunction":"Omit first two books where author has three or more books\nTitle: Java, Author: John Doe, Age: 50, Published: 1998-01-01\nTitle: Python, Author: John Doe, Age: 62, Published: 2010-12-02\nTitle: Scala, Author: John Doe, Age: 67, Published: 2015-03-02\nTitle: C++, Author: William Fence, Age: 38, Published: 1990-04-02\nTitle: C, Author: William Fence, Age: 38, Published: 1990-04-14\nTitle: C#, Author: William Fence, Age: 60, Published: 2012-10-02\nFirst book where author has three or more books\nTitle: C++, Author: John Doe, Age: 42, Published: 1990-01-07\nTitle: Lisp, Author: William Fence, Age: 25, Published: 1977-09-24\nLast book where author has three or more books\nTitle: Scala, Author: John Doe, Age: 67, Published: 2015-03-02\nTitle: C#, Author: William Fence, Age: 60, Published: 2012-10-02\n","UniquePublishingDatesFromAuthorWithThreeOrMoreBooks":"Unique signing events on day of publication by authors with three or more books.\nDate: 1977-09-24\nDate: 1982-04-14\nDate: 1990-01-07\nDate: 1990-04-02\nDate: 1990-04-14\nDate: 1998-01-01\nDate: 2010-12-02\nDate: 2012-10-02\nDate: 2015-03-02\nBooks From author with three or more books\nTitle: C++, Author: John Doe, Age: 42, Published: 1990-01-07\nTitle: C, Author: John Doe, Age: 42, Published: 1990-01-07\nTitle: Java, Author: John Doe, Age: 50, Published: 1998-01-01\nTitle: Python, Author: John Doe, Age: 62, Published: 2010-12-02\nTitle: Scala, Author: John Doe, Age: 67, Published: 2015-03-02\nTitle: Lisp, Author: William Fence, Age: 25, Published: 1977-09-24\nTitle: Haskell, Author: William Fence, Age: 30, Published: 1982-04-14\nTitle: C++, Author: William Fence, Age: 38, Published: 1990-04-02\nTitle: C, Author: William Fence, Age: 38, Published: 1990-04-14\nTitle: C#, Author: William Fence, Age: 60, Published: 2012-10-02\nThere are 7 authors in total with any number of books\n","LibraryExample":"John Doe\nWilliam Fence\nMark Keely\nJames Pickford\nMark Pickford\n","SplitBooksByEra":"First book from each group, a new group starting at each modern book\nTitle: Lisp, Author: William Fence, Age: 25, Published: 1977-09-24\nTitle: Javascript, Author: James Pickford, Age: 52, Published: 2008-03-02\nTitle: CSS, Author: Mark Keely, Age: 51, Published: 2008-04-02\nTitle: HTML, Author: Mark Pickford, Age: 58, Published: 2008-07-02\nTitle: Python, Author: John Doe, Age: 62, Published: 2010-12-02\nTitle: C#, Author: William Fence, Age: 60, Published: 2012-10-02\nTitle: Scala, Author: John Doe, Age: 67, Published: 2015-03-02\nTitle: Dart, Author: Peter Dove, Age: 47, Published: 2020-01-02\n","GroupBooksByEra":"First book from each era (pre-2000 and 2000+)\nTitle: Lisp, Author: William Fence, Age: 25, Published: 1977-09-24\nTitle: Javascript, Author: James Pickford, Age: 52, Published: 2008-03-02\n","ImperativeLibraryExample":"John Doe\nMark Pickford\nMark Keely\nWilliam Fence\nJames Pickford\n"},"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"structure/structure_applications.ek9","url":"https://ek9.io/examples/structure/structure_applications.html","title":"Components, applications and programs that select them","code":"#!ek9\ndefines module site.structure.applications\n\n  defines component\n\n    BaseConfiguration as abstract\n      getFileStoreName() as abstract\n        <- rtn as String?\n\n    MainStoreSolution extends BaseConfiguration\n      override getFileStoreName()\n        <- rtn as String: \"MainStore\"\n\n    SecondaryStoreSolution extends BaseConfiguration\n      override getFileStoreName()\n        <- rtn as String: \"SecondaryStore\"\n\n    DefaultStoreSolution extends BaseConfiguration\n      override getFileStoreName()\n        <- rtn as String: \"DefaultStore\"\n\n    DataCache as abstract\n      cacheName() as abstract\n        <- rtn as String?\n\n    RedisCache extends DataCache\n      override cacheName()\n        <- rtn as String: \"Redis\"\n\n    MemCached extends DataCache\n      override cacheName()\n        <- rtn as String: \"MemCached\"\n\n  defines application\n\n    AppV1\n      register MainStoreSolution() as BaseConfiguration\n      register RedisCache() as DataCache\n\n    AppV2\n      register SecondaryStoreSolution() as BaseConfiguration\n      register RedisCache() as DataCache\n\n    AppV3\n      register DefaultStoreSolution() as BaseConfiguration\n      register MemCached() as DataCache\n\n  defines class\n\n    ConfigHandler\n      //Because BaseConfiguration is an abstract component it will get injected\n      //Note the use of the ! suffix\n      config as BaseConfiguration!\n\n      showConfigDetails()\n        stdout <- Stdout()\n        stdout.println(config.getFileStoreName())\n\n      default operator ?\n\n  defines program\n\n    v1Program with application of AppV1\n      configHandler <- ConfigHandler()\n      configHandler.showConfigDetails()\n\n    v2Program with application of AppV2\n      configHandler <- ConfigHandler()\n      configHandler.showConfigDetails()\n\n    v3Program with application of AppV3\n      configHandler <- ConfigHandler()\n      configHandler.showConfigDetails()","expectedOutput":{"v1Program":"MainStore\n","v2Program":"SecondaryStore\n","v3Program":"DefaultStore\n"},"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"structure/structure_cardsuit.ek9","url":"https://ek9.io/examples/structure/structure_cardsuit.html","title":"An enumeration type","code":"#!ek9\ndefines module site.structure.cardsuit\n\n  defines type\n    CardSuit\n      Hearts\n      Diamonds\n      Clubs\n      Spades","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"structure/structure_classes.ek9","url":"https://ek9.io/examples/structure/structure_classes.html","title":"Abstract, closed and open classes","code":"#!ek9\ndefines module site.structure.classes\n\n  defines class\n  \n    //If you say it is abstract then it is by default 'open' so it can be extended\n    Base as abstract\n      singleMethod() as abstract\n        <- rtn as String?\n        \n    //This cannot be extended as it is not 'abstract' nor 'open'\n    Extension1 extends Base\n\n      //declaration and initialisation of a field/property\n      aField as Boolean: true\n      //Inferred type supported for simple unset declarations\n      bField <- String()\n\n      updateAdditionalFields()\n        -> additional as String\n        bField :=: additional\n\n      otherMethod()\n        <- rtn String: $ aField\n      \n      //must provide this method as Base has declared it but not implemented it.  \n      override singleMethod()\n        <- rtn String: \"Steve\"\n\n      default operator ?\n        \n    //Because this is marked as 'open' it can be used and extended\n    Extension2 extends Base as open\n      override singleMethod()\n        <- rtn String = \"Steven\"\n        \n    Extension3 extends Extension2\n      override singleMethod()\n        <- rtn String := \"Stephen\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"structure/structure_constants.ek9","url":"https://ek9.io/examples/structure/structure_constants.html","title":"Two constants","code":"#!ek9\ndefines module site.structure.constants\n\n  defines constant\n    PI <- 3.142    \n    e <- 2.71828","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"structure/structure_declarations.ek9","url":"https://ek9.io/examples/structure/structure_declarations.html","title":"Declaring variables with and without type inference","code":"#!ek9\ndefines module site.structure.declarations\n\n  defines program\n\n    Declarations()\n      stdout <- Stdout()\n\n      name1 as String?\n      name2 as String := String()\n      name3 as String := \"Some Value\"\n      name4 as String := String(\"Some Value\")\n\n      //Inferred type declaration\n      name5 <- \"Another Value\"\n      name6 <- String()\n\n      name1: \"Assigned later\"\n      stdout.println(`${name1} ${name2?} ${name3} ${name4} ${name5} ${name6?}`)","expectedOutput":"Assigned later false Some Value Some Value Another Value false\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"structure/structure_filter.ek9","url":"https://ek9.io/examples/structure/structure_filter.html","title":"An abstract function, two functions that extend it, and a delegate","code":"#!ek9\ndefines module site.structure.filter\n  defines function\n  \n    //Just a function signature.\n    stringFilter() as abstract    \n      -> string as String\n      <- rtn as Boolean?\n      \n    nonColon() extends stringFilter()\n      -> string as String\n      <- rtn as Boolean: \":\" <> string\n        \n    isSet() extends stringFilter()\n      -> string as String\n      <- rtn as Boolean: string?\n        \n  defines program\n  \n    TestFilter()\n      stdout <- Stdout()\n      toTest <- \"Steve\"\n      \n      if nonColon(toTest)\n        stdout.println(toTest + \" does not have a colon\")\n      else\n        stdout.println(toTest + \" does have a colon\")\n      \n      //It is also possible via delegate access\n      acceptable as stringFilter := nonColon\n      if acceptable(toTest)\n        stdout.println(toTest + \" does not have a colon\")\n      \n      //As a delegate we can swap the function out for another compatible one.\n      acceptable = isSet\n      if not acceptable(toTest)\n        stdout.println(\"The value toTest is not set\")","expectedOutput":"Steve does not have a colon\nSteve does not have a colon\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"structure/structure_fsm.ek9","url":"https://ek9.io/examples/structure/structure_fsm.html","title":"A generic finite state machine with a listener","code":"#!ek9\ndefines module site.structure.fsm\n\n  defines type\n\n    FSM of Integer\n\n  defines function\n\n    FSMListener() of type T as abstract\n      ->\n        fromState as T\n        toState as T\n\n  defines class\n\n    FSM of type T\n      currentState as T: T()\n      listener as FSMListener of T?\n\n      FSM()\n        -> initialState as T\n        require initialState?\n        currentState: initialState\n        listener: () is FSMListener of T as function\n          require fromState? and toState?\n\n      default private FSM()\n\n      setState()\n        -> newState as T\n        require newState?\n        if listener?\n          listener(currentState, newState)\n        currentState: newState\n\n      getState()\n        <- rtn as T: currentState\n\n      setListener()\n        -> listenerToAdd as FSMListener of T\n        require listenerToAdd?\n        listener: listenerToAdd\n\n      default operator ?\n\n  defines program\n\n    Driver()\n      myListener <- () is FSMListener of Integer as function\n        stdout <- Stdout()\n        require fromState? and toState?\n        stdout.println(`Changing from ${fromState} to ${toState}`)\n\n      myMachine <- FSM(2)\n      myMachine.setListener(myListener)\n      myMachine.setState(5)","expectedOutput":"Changing from 2 to 5\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"structure/structure_generic_function.ek9","url":"https://ek9.io/examples/structure/structure_generic_function.html","title":"A generic function used through dynamic functions","code":"#!ek9\ndefines module site.structure.genericfunction\n\n  defines function\n  \n    compareFunction() of type T as open\n      ->\n        item1 as T\n        item2 as T\n      <-\n        rtn as Integer: item1 <=> item2  \n\n  defines program\n  \n    ComparatorDemo()\n      stdout <- Stdout()\n      intComparator <- () is compareFunction of Integer as function\n      stringComparator <- () extends compareFunction of String as function\n      \n      intResult <- intComparator(2, 8)\n      stringResult <- stringComparator(\"two\", \"eight\")\n\n      stdout.println(`Result of int comparison is ${intResult}`)\n      stdout.println(`Result of string comparison is ${stringResult}`)","expectedOutput":"Result of int comparison is -1\nResult of string comparison is 15\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"structure/structure_hello.ek9","url":"https://ek9.io/examples/structure/structure_hello.html","title":"Two programs and a constant","code":"#!ek9\ndefines module site.structure.hello\n\n  defines constant\n    worldMessage <- \"Hello, World\"\n    \n  defines program\n    HelloWorld()\n      stdout <- Stdout()\n      stdout.println(worldMessage)\n      \n    HelloMars()\n      stdout <- Stdout()\n      stdout.println(\"Hello, Mars\")","expectedOutput":{"HelloWorld":"Hello, World\n","HelloMars":"Hello, Mars\n"},"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"structure/structure_module.ek9","url":"https://ek9.io/examples/structure/structure_module.html","title":"The start of a source file","code":"#!ek9\ndefines module site.structure.layout","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"structure/structure_no_semicolon.ek9","url":"https://ek9.io/examples/structure/structure_no_semicolon.html","title":"A statement ends at the end of its line","code":"#!ek9\ndefines module site.structure.nosemicolon\n\n  defines program\n\n    Greeting()\n      name <- \"Steve\"\n      Stdout().println(name)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"structure/structure_person.ek9","url":"https://ek9.io/examples/structure/structure_person.html","title":"A Person record and a program that uses it","code":"#!ek9\ndefines module site.structure.person\n\n  defines record\n    Person\n      first as String: String()\n      last <- String()\n      dob <- Date()\n      profession <- String()\n\n      override operator ? as pure\n        <- rtn as Boolean: first? and last? and dob? and profession?\n\n      operator $ as pure\n        <- rtn as String: `${first}, ${last}, ${dob}, ${profession}`\n\n      operator == as pure\n        -> other as Person\n        <- rtn as Boolean: other? and first == other.first and last == other.last and dob == other.dob\n\n      operator #? as pure\n        <- rtn as Integer: #? first + #? last + #? dob\n\n  defines program\n\n    InferenceExample()\n      smithj <- Person()\n\n      //Different ways of assigning value\n      smithj.first: \"John\"\n      smithj.last := \"Smith\"\n      smithj.dob = 1960-01-01\n      smithj.profession: \"IT\"\n\n      firstName <- smithj.first\n      Stdout().println(`${firstName} - ${smithj}`)","expectedOutput":"John - John, Smith, 1960-01-01, IT\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"structure/structure_person_alias.ek9","url":"https://ek9.io/examples/structure/structure_person_alias.html","title":"A record field stored with ':' shares the caller's object; a copy constructor or ':=:' gives the record its own","code":"#!ek9\ndefines module site.structure.personalias\n\n  defines record\n\n    Person\n      first as String: String()\n      last <- String()\n      profession <- String()\n\n      default Person()\n\n      Person()\n        ->\n          first as String\n          last as String\n          profession as String\n        //Keeps a reference to the caller's String\n        this.first: first\n        //The copy constructor: the record gets its own String\n        this.last: String(last)\n        //The copy operator: copies the value into the record's own String\n        this.profession :=: profession\n\n      override operator ? as pure\n        <- rtn as Boolean: first? and last? and profession?\n\n      operator $ as pure\n        <- rtn as String: `${first}, ${last}, ${profession}`\n\n  defines program\n\n    SharedOrCopied()\n      stdout <- Stdout()\n\n      firstName <- \"John\"\n      lastName <- \"Smith\"\n      jobTitle <- \"IT\"\n      smithj <- Person(firstName, lastName, jobTitle)\n      stdout.println(smithj)\n\n      //The caller changes its own Strings in place\n      firstName += \" Jr\"\n      lastName += \" Jr\"\n      jobTitle += \" Manager\"\n      stdout.println(`${firstName}, ${lastName}, ${jobTitle}`)\n\n      //Only 'first' changed: it is the caller's String\n      stdout.println(smithj)","expectedOutput":"John, Smith, IT\nJohn Jr, Smith Jr, IT Manager\nJohn Jr, Smith, IT\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"structure/structure_person_alias_unread.ek9","url":"https://ek9.io/examples/structure/structure_person_alias_unread.html","title":"Changing an argument the record shares, then never reading it","code":"#!ek9\ndefines module bad.site.structure.personaliasunread\n\n  defines record\n\n    Person\n      first as String: String()\n\n      default Person()\n\n      Person()\n        -> first as String\n        this.first: first\n\n      override operator ? as pure\n        <- rtn as Boolean: first?\n\n      operator $ as pure\n        <- rtn as String: first\n\n  defines program\n\n    ChangedButNeverRead()\n      stdout <- Stdout()\n      firstName <- \"John\"\n      smithj <- Person(firstName)\n      firstName += \" Jr\"\n      stdout.println(smithj)","expectedOutput":null,"kind":"bad","errors":["E08090"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"structure/structure_person_named.ek9","url":"https://ek9.io/examples/structure/structure_person_named.html","title":"A record constructor that copies its arguments, called with named arguments","code":"#!ek9\ndefines module site.structure.personnamed\n\n  defines record\n\n    Person\n      first as String: String()\n      last <- String()\n      dob <- Date()\n      profession <- String()\n\n      default Person()\n\n      Person()\n        ->\n          first as String\n          last as String\n          dob as Date\n          profession as String\n        //Each field gets its own copy, so the caller's objects stay the caller's\n        this.first: String(first)\n        this.last: String(last)\n        this.dob: Date(dob)\n        this.profession: String(profession)\n\n      override operator ? as pure\n        <- rtn as Boolean: first? and last? and dob? and profession?\n\n      operator $ as pure\n        <- rtn as String: `${first}, ${last}, ${dob}, ${profession}`\n\n  defines program\n\n    NamedArguments()\n      stdout <- Stdout()\n\n      smithj <- Person(first: \"John\", last: \"Smith\", dob: 1960-01-01, profession: \"IT\")\n\n      stdout.println(smithj)","expectedOutput":"John, Smith, 1960-01-01, IT\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"structure/structure_security.ek9","url":"https://ek9.io/examples/structure/structure_security.html","title":"Registering a security provider component","code":"#!ek9\ndefines module site.structure.security\n\n  defines component\n\n    SecurityProvider as abstract\n      providerName() as abstract\n        <- rtn as String?\n\n    SimpleDevelopedSecurityProvider extends SecurityProvider\n      override providerName()\n        <- rtn as String: \"Simple developed security provider\"\n\n  defines application\n\n    SecuredApplication\n      register SimpleDevelopedSecurityProvider() as SecurityProvider\n\n  defines program\n\n    Secured() with application of SecuredApplication\n      stdout <- Stdout()\n      provider as SecurityProvider!\n      stdout.println(provider.providerName())","expectedOutput":"Simple developed security provider\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"structure/structure_semicolon.ek9","url":"https://ek9.io/examples/structure/structure_semicolon.html","title":"A semicolon at the end of a statement","code":"#!ek9\ndefines module bad.site.structure.semicolon\n\n  defines program\n\n    Greeting()\n      name <- \"Steve\";\n      Stdout().println(name)","expectedOutput":null,"kind":"bad","errors":["E01074"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"structure/structure_services.ek9","url":"https://ek9.io/examples/structure/structure_services.html","title":"Two services, their application and the program that serves them","code":"#!ek9\ndefines module site.structure.services\n\n  defines component\n\n    BusinessProcess as abstract\n      process() as abstract\n        -> detail as String\n        <- rtn as String?\n\n    StandardBusinessProcess extends BusinessProcess\n      override process()\n        -> detail as String\n        <- rtn as String: `{\"processed\": \"${detail}\"}`\n\n  defines function\n\n    //Every operation below answers through this one response, to keep the example short.\n    jsonResponse() as pure\n      -> json as String\n      <- response as HTTPResponse: (json) with trait of HTTPResponse\n        override content()\n          <- rtn as Bytes: Bytes().withUtf8(json)\n        override status() as pure\n          <- rtn as Integer: 200\n        override contentType() as pure\n          <- rtn as String: \"application/json\"\n        override cacheControl() as pure\n          <- rtn as String: \"no-cache\"\n        override contentLanguage() as pure\n          <- rtn as String: \"en\"\n        default operator ?\n\n  defines service\n\n    Addresses for :/addresses open\n\n      //A GET (the default verb for a named operation)\n      byId() for :/{address-id}\n        ->\n          addressId as String :=: PATH \"address-id\" //required because different name\n          acceptLanguage as String :=: HEADER \"Accept-Language\"\n        <-\n          response as HTTPResponse: jsonResponse(`{\"id\": \"${addressId}\", \"language\": \"${acceptLanguage}\"}`)\n\n      listByPostCode() for :/{postCode}/\n        ->\n          postCode as String //Now assume PATH PARAM because there is a param\n          acceptLanguage as String :=: HEADER \"Accept-Language\"\n        <-\n          response as HTTPResponse: jsonResponse(`{\"postCode\": \"${postCode}\", \"language\": \"${acceptLanguage}\"}`)\n\n      list() for :/\n        ->\n          postCode as String :=: QUERY \"postCode\"\n          acceptLanguage as String :=: HEADER \"Accept-Language\"\n        <-\n          response as HTTPResponse: jsonResponse(`{\"query\": \"${postCode}\", \"language\": \"${acceptLanguage}\"}`)\n\n      //A POST adds to the collection\n      operator += for :/\n        -> request as HTTPRequest :=: REQUEST\n        <-\n          response as HTTPResponse: jsonResponse(request.content().toText(\"utf-8\"))\n\n      //A DELETE removes from it\n      operator -= for :/{addressId}\n        -> addressId as String\n        <-\n          response as HTTPResponse: jsonResponse(`{\"deleted\": \"${addressId}\"}`)\n\n      //A PUT replaces a resource\n      operator :^: for :/{addressId}\n        ->\n          addressId as String //assume PATH\n          content as String :=: CONTENT\n        <-\n          response as HTTPResponse: jsonResponse(`{\"replaced\": \"${addressId}\", \"with\": ${content}}`)\n\n      //merge is a PATCH\n      operator :~: for :/{addressId}\n        ->\n          addressId as String //assume PATH\n          content as String :=: CONTENT\n        <-\n          response as HTTPResponse: jsonResponse(`{\"merged\": \"${addressId}\", \"with\": ${content}}`)\n\n    //Here is customer service (only partial)\n    //But shows verbs 'GET', 'PUT' etc named explicitly\n    Customers for :/customers open\n\n      //Just get by customer identifier\n      //i.e http(s):somehostorother.com/customers/CUST-ABCD\n      byId() as GET for :/{customerId}\n        ->\n          customerId as String :=: PATH\n          acceptLanguage as String :=: HEADER \"Accept-Language\"\n        <-\n          response as HTTPResponse: jsonResponse(`{\"customer\": \"${customerId}\", \"language\": \"${acceptLanguage}\"}`)\n\n      replace() as PUT for :/{customerId}\n        ->\n          customerId as String :=: PATH\n          content as String :=: CONTENT\n        <-\n          response as HTTPResponse: (customerId, content) with trait of HTTPResponse\n            businessProcess as BusinessProcess! // this gets injected as a component\n            //Now use the business process to build the response.\n            override content()\n              <- rtn as Bytes: Bytes().withUtf8(businessProcess.process(`${customerId} ${content}`))\n            override status() as pure\n              <- rtn as Integer: 200\n            override contentType() as pure\n              <- rtn as String: \"application/json\"\n            override cacheControl() as pure\n              <- rtn as String: \"no-store\"\n            override contentLanguage() as pure\n              <- rtn as String: \"en\"\n            default operator ?\n\n  //Application that exposes the web services to be made available.\n  defines application\n\n    CustomerAccess\n      //Register the business component\n      register StandardBusinessProcess() as BusinessProcess\n\n      //Now register the services to be made available.\n      register Customers()\n      register Addresses()\n\n  //A program that starts up the REST server with the configuration above\n  defines program\n\n    RestWebApp() with application of CustomerAccess\n      stdout <- Stdout()\n      stdout.println(\"Now starting REST Services\")\n\n      //Serve on socket port 9092, until the server is stopped.\n      try\n        -> server <- HTTP(NetworkProperties(9092))\n        server.serve()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"structure/structure_shapes.ek9","url":"https://ek9.io/examples/structure/structure_shapes.html","title":"A sealed trait controlling a class hierarchy","code":"#!ek9\ndefines module site.structure.shapes\n\n  defines trait\n\n    ShapeLimit allow only Ellipse, Circle, Rectangle, Square, Triangle\n      printDrawing()\n        -> message as String\n        //method body\n        stdout <- Stdout()\n        stdout.println(message)\n\n  defines class\n\n    Shape with trait of ShapeLimit as abstract\n      draw() as abstract\n\n    Ellipse extends Shape as open\n      override draw()\n        printDrawing(\"Ellipse\")\n\n    Circle extends Ellipse\n      override draw()\n        printDrawing(\"Circle\")\n\n    Rectangle extends Shape\n      override draw()\n        printDrawing(\"Rectangle\")\n\n    Triangle extends Shape\n      override draw()\n        printDrawing(\"Triangle\")\n\n    Square extends Shape\n      override draw()\n        printDrawing(\"Square\")\n\n  defines program\n\n    DrawShapes()\n      for shape in [Ellipse(), Circle(), Rectangle(), Square(), Triangle()]\n        shape.draw()","expectedOutput":"Ellipse\nCircle\nRectangle\nSquare\nTriangle\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"structure/structure_shapes_shorthand.ek9","url":"https://ek9.io/examples/structure/structure_shapes_shorthand.html","title":"Shorthand for a trait and for extending a class","code":"#!ek9\ndefines module site.structure.shapesshorthand\n\n  defines trait\n\n    ShapeLimit allow only Ellipse\n      printDrawing()\n        -> message as String\n        Stdout().println(message)\n\n  defines class\n\n    //Could have been written in shorthand like this\n    Shape with trait ShapeLimit as abstract\n      draw() as abstract\n\n    //This could have been written like this\n    Ellipse is Shape as open\n      override draw()\n        printDrawing(\"Ellipse\")\n\n  defines program\n\n    DrawShorthand()\n      Ellipse().draw()","expectedOutput":"Ellipse\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"structure/structure_text.ek9","url":"https://ek9.io/examples/structure/structure_text.html","title":"Text with interpolation","code":"#!ek9\ndefines module site.structure.text\n\n  defines record\n\n    Product\n      name <- String()\n\n      Product()\n        -> productName as String\n        name: productName\n\n      default operator ?\n\n  defines text for \"en\"\n     \n    //Define some text in English and wrap in a 'text' object.\n    ProductsText\n      productsTitle\n        \"Products\"\n      productFineDetails()\n        \"The fine details\"\n      share\n        \"Share\"\n      moreDetailsOn()\n        -> product as Product\n        `More details on ${product.name}`\n        \n  defines program\n  \n    TestText\n      stdout <- Stdout()\n      text <- ProductsText(\"en\")\n      \n      specialProduct <- Product(\"Special\")\n      stdout.println(text.productsTitle())\n      stdout.println(text.moreDetailsOn(specialProduct))","expectedOutput":"Products\nMore details on Special\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testGeneration/account/testGeneration_account.ek9","url":"https://ek9.io/examples/testGeneration/account/testGeneration_account.html","title":"A small library to generate tests and mutations for","code":"#!ek9\ndefines module site.testgeneration.account\n\n  defines class\n\n    Account\n      balance as Integer: 0\n\n      Account()\n        -> initialBalance as Integer\n        balance: initialBalance\n\n      deposit()\n        -> amount as Integer\n        if amount > 0\n          balance += amount\n\n      current() as pure\n        <- rtn as Integer: balance\n\n      operator $ as pure\n        <- rtn as String: `Account(${balance})`\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/assertions/dev/testing_assertions_tests.ek9","url":"https://ek9.io/examples/testing/assertions/dev/testing_assertions_tests.html","title":"Test code: assert, assertThrows and assertDoesNotThrow","code":"#!ek9\ndefines module site.testing.assertions.tests\n\n  references\n    site.testing.assertions::checkedDivide\n\n  defines program\n\n    @Test\n    CheckDivision()\n      result <- checkedDivide(10, 2)\n      assert result?          //Check result is set (not unset)\n      assert result == 5      //Check result equals the expected value\n\n    @Test\n    CheckDivisionByZero()\n      assertThrows(Exception, checkedDivide(10, 0))\n\n    @Test\n    CheckAndInspectException()\n      caught <- assertThrows(Exception, checkedDivide(10, 0))\n      assert caught.reason() == \"division by zero\"\n\n    @Test\n    CheckSafeDivision()\n      assertDoesNotThrow(checkedDivide(10, 2))\n\n    @Test\n    CheckSafeDivisionResult()\n      //assertDoesNotThrow gives nothing back: check the value with its own assert\n      assertDoesNotThrow(checkedDivide(10, 2))\n      result <- checkedDivide(10, 2)\n      assert result == 5","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/assertions/testing_assertions.ek9","url":"https://ek9.io/examples/testing/assertions/testing_assertions.html","title":"Production code: a division that throws on a zero divisor","code":"#!ek9\ndefines module site.testing.assertions\n\n  defines function\n\n    checkedDivide() as pure\n      ->\n        dividend as Integer\n        divisor as Integer\n      <- quotient as Integer?\n\n      //Integer division by zero does not throw: it gives an unset Integer.\n      //So a function that must fail says so explicitly.\n      if divisor == 0\n        throw Exception(\"division by zero\")\n      quotient: dividend / divisor","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/assertionsfail/dev/testing_assertionsfail_tests.ek9","url":"https://ek9.io/examples/testing/assertionsfail/dev/testing_assertionsfail_tests.html","title":"Three tests that fail, one per assertion","code":"#!ek9\ndefines module site.testing.assertionsfail.tests\n\n  references\n    site.testing.assertionsfail::checkedDivide\n\n  defines program\n\n    @Test\n    WrongQuotient()\n      result <- checkedDivide(10, 2)\n      assert result == 6\n\n    @Test\n    ExpectsAThrowThatNeverComes()\n      assertThrows(Exception, checkedDivide(10, 2))\n\n    @Test\n    DoesNotExpectTheThrow()\n      assertDoesNotThrow(checkedDivide(10, 0))","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/assertionsfail/testing_assertionsfail.ek9","url":"https://ek9.io/examples/testing/assertionsfail/testing_assertionsfail.html","title":"The same division, under tests that are wrong","code":"#!ek9\ndefines module site.testing.assertionsfail\n\n  defines function\n\n    checkedDivide() as pure\n      ->\n        dividend as Integer\n        divisor as Integer\n      <- quotient as Integer?\n\n      if divisor == 0\n        throw Exception(\"division by zero\")\n      quotient: dividend / divisor","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/asserts/dev/testing_asserts_tests.ek9","url":"https://ek9.io/examples/testing/asserts/dev/testing_asserts_tests.html","title":"Test code: three assert-based tests","code":"#!ek9\ndefines module site.testing.asserts.tests\n\n  references\n    site.testing.asserts::add\n    site.testing.asserts::multiply\n\n  defines program\n\n    @Test\n    AdditionTest()\n      result <- add(2, 3)\n      assert result?\n      assert result == 5\n\n    @Test\n    MultiplicationTest()\n      result <- multiply(4, 5)\n      assert result?\n      assert result == 20\n\n    @Test\n    CombinedOperationsTest()\n      sum <- add(10, 20)\n      product <- multiply(sum, 2)\n      assert product == 60","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/asserts/testing_asserts.ek9","url":"https://ek9.io/examples/testing/asserts/testing_asserts.html","title":"Production code: the functions to test","code":"#!ek9\ndefines module site.testing.asserts\n\n  defines function\n\n    add() as pure\n      ->\n        a as Integer\n        b as Integer\n      <- result as Integer: a + b\n\n    multiply() as pure\n      ->\n        a as Integer\n        b as Integer\n      <- result as Integer: a * b","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/blackbox/dev/testing_blackbox_tests.ek9","url":"https://ek9.io/examples/testing/blackbox/dev/testing_blackbox_tests.html","title":"Test code: the output is the assertion","code":"#!ek9\ndefines module site.testing.blackbox.tests\n\n  references\n    site.testing.blackbox::greet\n\n  defines program\n\n    @Test\n    GreetingOutputTest()\n      stdout <- Stdout()\n      stdout.println(greet(\"World\"))\n      stdout.println(greet(\"EK9\"))","expectedOutput":{"GreetingOutputTest":"Hello, World!\nHello, EK9!\n"},"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/blackbox/testing_blackbox.ek9","url":"https://ek9.io/examples/testing/blackbox/testing_blackbox.html","title":"Production code: a greeting","code":"#!ek9\ndefines module site.testing.blackbox\n\n  defines function\n\n    greet() as pure\n      -> name as String\n      <- greeting as String: `Hello, ${name}!`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/blackboxfail/dev/testing_blackboxfail_tests.ek9","url":"https://ek9.io/examples/testing/blackboxfail/dev/testing_blackboxfail_tests.html","title":"The same black-box test, against the defect","code":"#!ek9\ndefines module site.testing.blackboxfail.tests\n\n  references\n    site.testing.blackboxfail::greet\n\n  defines program\n\n    @Test\n    GreetingOutputTest()\n      stdout <- Stdout()\n      stdout.println(greet(\"World\"))\n      stdout.println(greet(\"EK9\"))","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/blackboxfail/testing_blackboxfail.ek9","url":"https://ek9.io/examples/testing/blackboxfail/testing_blackboxfail.html","title":"A defect: the greeting ends with '?'","code":"#!ek9\ndefines module site.testing.blackboxfail\n\n  defines function\n\n    greet() as pure\n      -> name as String\n      <- greeting as String: `Hello, ${name}?`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/exitcode/dev/testing_exitcode_tests.ek9","url":"https://ek9.io/examples/testing/exitcode/dev/testing_exitcode_tests.html","title":"Test code: each test judges the exit code its program returns","code":"#!ek9\ndefines module site.testing.exitcode.tests\n\n  references\n    site.testing.exitcode::exitCodeFor\n\n  defines constant\n    validOrder <- \"order-42\"\n    noOrder <- \"\"\n\n  defines program\n\n    @Test\n    ValidInputExitsZero()\n      <- rtn as Integer: exitCodeFor(validOrder)\n      assert rtn?\n\n    @Test: \"EXIT:3\"\n    EmptyInputExitsThree()\n      <- rtn as Integer: exitCodeFor(noOrder)\n      assert rtn?\n\n    @Test: \"REQ:input-validation\": \"validation\": \"EXIT:3\"\n    AnchoredGroupedExitsThree()\n      <- rtn as Integer: exitCodeFor(noOrder)\n      assert rtn?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/exitcode/testing_exitcode.ek9","url":"https://ek9.io/examples/testing/exitcode/testing_exitcode.html","title":"Production code: the exit code an input earns","code":"#!ek9\ndefines module site.testing.exitcode\n\n  defines function\n\n    exitCodeFor() as pure\n      -> input as String\n      <- rtn as Integer: 0\n      if input is empty\n        rtn: 3","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/failing/dev/testing_failing_tests.ek9","url":"https://ek9.io/examples/testing/failing/dev/testing_failing_tests.html","title":"The same test, run against the defect","code":"#!ek9\ndefines module site.testing.failing.tests\n\n  references\n    site.testing.failing::add\n\n  defines program\n\n    @Test\n    AdditionWorks()\n      result <- add(2, 3)\n      assert result == 5","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/failing/testing_failing.ek9","url":"https://ek9.io/examples/testing/failing/testing_failing.html","title":"A defect the test will find: add multiplies","code":"#!ek9\ndefines module site.testing.failing\n\n  defines function\n\n    add() as pure\n      ->\n        a as Integer\n        b as Integer\n      <- result as Integer: a * b","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/first/dev/testing_first_tests.ek9","url":"https://ek9.io/examples/testing/first/dev/testing_first_tests.html","title":"The test, in dev/","code":"#!ek9\ndefines module site.testing.first.tests\n\n  references\n    site.testing.first::add\n\n  defines program\n\n    @Test\n    AdditionWorks()\n      result <- add(2, 3)\n      assert result == 5","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/first/testing_first.ek9","url":"https://ek9.io/examples/testing/first/testing_first.html","title":"The code to test","code":"#!ek9\ndefines module site.testing.first\n\n  defines function\n\n    add() as pure\n      ->\n        a as Integer\n        b as Integer\n      <- result as Integer: a + b","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/formats/dev/testing_formats_tests.ek9","url":"https://ek9.io/examples/testing/formats/dev/testing_formats_tests.html","title":"Four tests: two pass, two find the defect","code":"#!ek9\ndefines module site.testing.formats.tests\n\n  references\n    site.testing.formats::add\n    site.testing.formats::subtract\n\n  defines program\n\n    @Test\n    AdditionWorks()\n      assert add(2, 3) == 5\n\n    @Test\n    AdditionIsCommutative()\n      assert add(2, 3) == add(3, 2)\n\n    @Test\n    SubtractionWorks()\n      result <- subtract(5, 3)\n      assert result == 2\n\n    @Test\n    SubtractionOfZero()\n      assert subtract(7, 0) == 7","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/formats/testing_formats.ek9","url":"https://ek9.io/examples/testing/formats/testing_formats.html","title":"Production code for the output formats: two functions, one of them wrong","code":"#!ek9\ndefines module site.testing.formats\n\n  defines function\n\n    add() as pure\n      ->\n        a as Integer\n        b as Integer\n      <- result as Integer: a + b\n\n    //A defect, for the failing tests to find: it subtracts\n    subtract() as pure\n      ->\n        a as Integer\n        b as Integer\n      <- result as Integer: b - a","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/grouped/dev/testing_grouped_tests.ek9","url":"https://ek9.io/examples/testing/grouped/dev/testing_grouped_tests.html","title":"Test code: two tests in the \"counter\" group, one ungrouped","code":"#!ek9\ndefines module site.testing.grouped.tests\n\n  references\n    site.testing.grouped::Counter\n\n  defines program\n\n    @Test: \"counter\"\n    CounterIncrementTest()\n      counter <- Counter()\n      counter.increment()\n      assert counter.count() == 1\n\n    @Test: \"counter\"\n    CounterMultipleIncrementTest()\n      counter <- Counter()\n      counter.increment()\n      counter.increment()\n      counter.increment()\n      assert counter.count() == 3\n\n    @Test\n    IndependentTest()\n      counter <- Counter()\n      assert counter.count() == 0","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/grouped/testing_grouped.ek9","url":"https://ek9.io/examples/testing/grouped/testing_grouped.html","title":"Production code: a Counter class","code":"#!ek9\ndefines module site.testing.grouped\n\n  defines class\n\n    Counter\n      ticks as Integer: 0\n\n      count() as pure\n        <- rtn as Integer: ticks\n\n      increment()\n        ticks++\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/layout/dev/calculator/testing_layout_calculator.ek9","url":"https://ek9.io/examples/testing/layout/dev/calculator/testing_layout_calculator.html","title":"dev/calculator/: a parameterized test in a directory of its own","code":"#!ek9\ndefines module site.testing.layout.calculator\n\n  references\n    site.testing.layout::double\n\n  defines program\n\n    @Test\n    DoubleEachArgument()\n      -> amount as Integer\n      stdout <- Stdout()\n      stdout.println(double(amount))","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/layout/dev/greeting/testing_layout_greeting.ek9","url":"https://ek9.io/examples/testing/layout/dev/greeting/testing_layout_greeting.html","title":"dev/greeting/: a black-box test in a directory of its own","code":"#!ek9\ndefines module site.testing.layout.greeting\n\n  references\n    site.testing.layout::greet\n\n  defines program\n\n    @Test\n    GreetingOutput()\n      stdout <- Stdout()\n      stdout.println(greet(\"World\"))","expectedOutput":{"GreetingOutput":"Hello, World!\n"},"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/layout/dev/testing_layout_unit.ek9","url":"https://ek9.io/examples/testing/layout/dev/testing_layout_unit.html","title":"dev/testing_layout_unit.ek9: assert-based tests","code":"#!ek9\ndefines module site.testing.layout.unit\n\n  references\n    site.testing.layout::double\n    site.testing.layout::greet\n\n  defines program\n\n    @Test\n    GreetingIsPolite()\n      assert greet(\"Ada\") == \"Hello, Ada!\"\n\n    @Test\n    DoublingWorks()\n      assert double(21) == 42","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/layout/testing_layout.ek9","url":"https://ek9.io/examples/testing/layout/testing_layout.html","title":"Production code for the directory layout","code":"#!ek9\ndefines module site.testing.layout\n\n  defines function\n\n    greet() as pure\n      -> name as String\n      <- greeting as String: `Hello, ${name}!`\n\n    double() as pure\n      -> amount as Integer\n      <- result as Integer: amount * 2","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/parameterized/dev/testing_parameterized_tests.ek9","url":"https://ek9.io/examples/testing/parameterized/dev/testing_parameterized_tests.html","title":"Test code: a test program that takes parameters","code":"#!ek9\ndefines module site.testing.parameterized.tests\n\n  references\n    site.testing.parameterized::processArg\n\n  defines program\n\n    @Test\n    ArgProcessor()\n      ->\n        first as String\n        second as String\n\n      stdout <- Stdout()\n      stdout.println(processArg(first))\n      stdout.println(processArg(second))","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/parameterized/testing_parameterized.ek9","url":"https://ek9.io/examples/testing/parameterized/testing_parameterized.html","title":"Production code: the function each case drives","code":"#!ek9\ndefines module site.testing.parameterized\n\n  defines function\n\n    processArg() as pure\n      -> text as String\n      <- result as String: `Processed: ${text}`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/placeholders/dev/testing_placeholders_tests.ek9","url":"https://ek9.io/examples/testing/placeholders/dev/testing_placeholders_tests.html","title":"The black-box test of the report","code":"#!ek9\ndefines module site.testing.placeholders.tests\n\n  references\n    site.testing.placeholders::generateReport\n\n  defines program\n\n    @Test\n    ReportIncludesDate()\n      stdout <- Stdout()\n      stdout.println(generateReport(42))","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/placeholders/testing_placeholders.ek9","url":"https://ek9.io/examples/testing/placeholders/testing_placeholders.html","title":"A report generator whose output holds today's date","code":"#!ek9\ndefines module site.testing.placeholders\n\n  defines function\n\n    generateReport()\n      -> itemCount as Integer\n      <- report as String: `Report generated on ${Date().today()} with ${itemCount} items`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/quality/dev/testing_quality_good.ek9","url":"https://ek9.io/examples/testing/quality/dev/testing_quality_good.html","title":"The same test with descriptive names: it compiles","code":"#!ek9\ndefines module site.testing.quality\n\n  defines function\n\n    fetchUser()\n      <- rtn as String: \"Ada\"\n\n    processUser()\n      -> userName as String\n      <- rtn as String: `Processed ${userName}`\n\n  defines program\n\n    @Test\n    UserIsProcessed()\n      user <- fetchUser()\n      processedUser <- processUser(user)\n      assert processedUser?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"testing/qualitynames/dev/testing_qualitynames_bad.ek9","url":"https://ek9.io/examples/testing/qualitynames/dev/testing_qualitynames_bad.html","title":"Quality rules apply to test code: non-descriptive names","code":"#!ek9\ndefines module bad.site.testing.qualitynames\n\n  defines function\n\n    fetchUser()\n      <- rtn as String: \"Ada\"\n\n    processUser()\n      -> userName as String\n      <- rtn as String: `Processed ${userName}`\n\n  defines program\n\n    @Test\n    UserIsProcessed()\n      temp <- fetchUser()\n      data <- processUser(temp)\n      assert data?","expectedOutput":null,"kind":"bad","errors":["E11031"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (SiteBadExamplesTest, the -Psite gate step)","origin":"site"}
{"id":"testing/require/testing_require.ek9","url":"https://ek9.io/examples/testing/require/testing_require.html","title":"require: preconditions in production code","code":"#!ek9\ndefines module site.testing.require\n\n  defines type\n    OrderStatus\n      Created\n      Submitted\n\n  defines record\n    OrderItem\n      sku as String: String()\n      quantity as Integer: Integer()\n\n      OrderItem() as pure\n        ->\n          sku as String\n          quantity as Integer\n        this.sku :=? sku\n        this.quantity :=? quantity\n\n      default operator ?\n\n  defines class\n\n    Order\n      customerId as String: String()\n      items as List of OrderItem: List()\n      status as OrderStatus: OrderStatus.Created\n\n      //Constructor with preconditions - if these fail, the caller has a bug\n      Order()\n        ->\n          customerId as String\n          initialItems as List of OrderItem\n        require customerId?\n        require initialItems is not empty\n        this.customerId: customerId\n        items += initialItems\n\n      //Method with preconditions\n      addItem()\n        -> item as OrderItem\n        require item?\n        require status == OrderStatus.Created\n        items += item\n\n      //Method ensuring an invariant\n      submit()\n        require items is not empty\n        require status == OrderStatus.Created\n        status: OrderStatus.Submitted\n\n      default operator ?\n\n  defines program\n\n    OrderLifecycle()\n      stdout <- Stdout()\n      order <- Order(\"customer-7\", [OrderItem(\"widget\", 2)])\n      order.addItem(OrderItem(\"gadget\", 1))\n      order.submit()\n      stdout.println(\"Order submitted\")","expectedOutput":"Order submitted\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"textProperties/textProperties_welcome.ek9","url":"https://ek9.io/examples/textProperties/textProperties_welcome.html","title":"Text constructs for two locales, used from a program","code":"#!ek9\ndefines module site.textProperties.welcome\n\n  defines program\n\n    CheckTextAccess\n      stdout <- Stdout()\n\n      lang <- \"en_GB\"\n      me <- Person(\"Steve\", \"Limb\")\n      englishWelcome <- WelcomePageText(lang)\n      stdout.println(englishWelcome.mainWelcome())\n      stdout.println(englishWelcome.namedWelcome(me))\n\n      validator <- LanguageValidator(lang)\n      stdout.println(validator.valueTooShort(\"Some Long Input\"))\n\n      deutschWelcome <- WelcomePageText(\"de\")\n      stdout.println(deutschWelcome.mainWelcome())\n      stdout.println(deutschWelcome.namedWelcome(me))\n\n      nonSuchWelcome <- WelcomePageText(\"none\")\n      stdout.println(nonSuchWelcome.mainWelcome())\n      stdout.println(nonSuchWelcome.namedWelcome(me))\n\n  defines record\n    Person\n      firstName String: String()\n      lastName String: String()\n\n      Person()\n        ->\n          firstName String\n          lastName String\n        require firstName? and lastName?\n\n        this.firstName :=: firstName\n        this.lastName :=: lastName\n\n      operator $ as pure\n        <- rtn String: `${firstName} ${lastName}`\n\n      default operator ?\n\n  defines text for \"en_GB\"\n\n    WelcomePageText\n\n      namedWelcome()\n        -> person Person\n        `Welcome ${person.firstName}`\n\n      mainWelcome()\n        \"The main difference in processing html if you want to use hardwired content like this.\nYou must put it all in quotes.\nAs you can see above\\nwith welcomeMessage, EK9 will look for variable names,\nbut anything in double quotes check tab[\\t] is a literal.\nIn general you would probably use the 'text' mechanisms described in the section before this.\"\n\n      endWelcome()\n        `End Message.`\n\n    LanguageValidator\n      valueTooShort()\n        -> input as String\n        //Escape the $ with \\$ as it is used for interpolation\n        `The value:\n\\$ '${input}'\nyou entered is too short.\nThis can be multi-lined`\n\n      valueTooLong\n        -> input as String\n        `The value ${input} you entered is too long`\n\n      unknownLanguage\n        ->\n          input as String\n          constraint as String\n        `The value ${input} is not one of ${constraint}`\n\n  defines text for \"de\"\n\n    WelcomePageText\n      namedWelcome()\n        -> person Person\n        `Willkommen ${person.firstName}`\n\n      mainWelcome()\n        \"Der Hauptunterschied bei der Verarbeitung von HTML, wenn Sie fest verdrahteten Inhalt wie diesen verwenden möchten.\nSie müssen alles in Anführungszeichen setzen.\nWie Sie oben mit welcomeMessage sehen können, sucht EK9 nach Variablennamen.\naber alles in doppelten Anführungszeichen ist ein Literal.\nIm Allgemeinen würden Sie wahrscheinlich die im vorherigen Abschnitt beschriebenen 'Text'-Mechanismen verwenden.\"\n\n      endWelcome()\n        \"End Message.\"\n\n    LanguageValidator\n      valueTooShort()\n        -> input as String\n        `Der eingegebene Wert ${input} ist zu kurz`\n\n      valueTooLong\n        -> input as String\n        `Der von Ihnen eingegebene Wert ${input} ist zu lang`\n\n      unknownLanguage\n        ->\n          input as String\n          constraint as String\n        `Der Wert ${input} gehört nicht zu ${constraint}`","expectedOutput":"The main difference in processing html if you want to use hardwired content like this.\nYou must put it all in quotes.\nAs you can see above\nwith welcomeMessage, EK9 will look for variable names,\nbut anything in double quotes check tab[\t] is a literal.\nIn general you would probably use the 'text' mechanisms described in the section before this.\nWelcome Steve\nThe value:\n$ 'Some Long Input'\nyou entered is too short.\nThis can be multi-lined\nDer Hauptunterschied bei der Verarbeitung von HTML, wenn Sie fest verdrahteten Inhalt wie diesen verwenden möchten.\nSie müssen alles in Anführungszeichen setzen.\nWie Sie oben mit welcomeMessage sehen können, sucht EK9 nach Variablennamen.\naber alles in doppelten Anführungszeichen ist ein Literal.\nIm Allgemeinen würden Sie wahrscheinlich die im vorherigen Abschnitt beschriebenen 'Text'-Mechanismen verwenden.\nWillkommen Steve\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"traits/traits_processors.ek9","url":"https://ek9.io/examples/traits/traits_processors.html","title":"Traits, delegation with by, a sealed trait and a dispatcher","code":"#!ek9\ndefines module site.traits.processors\n\n  defines trait\n\n    CostAssessment\n      lowCost() as pure\n        <- rtn <- true\n\n    Moniterable\n      available() as pure\n        <- rtn <- true\n      lowCost() as pure\n        <- rtn <- false\n\n    Processor with trait of Moniterable, CostAssessment\n      process()\n        <- response as ProcessingResponse?\n\n      override lowCost() as pure\n        <- rtn as Boolean: CostAssessment.lowCost()\n\n    ProcessingResponse allow only StringResponse, StructuredResponse\n      result()\n        <- rtn as String?\n\n  defines class\n\n    StringResponse with trait of ProcessingResponse as open\n      theResponse as String: String()\n\n      StringResponse() as pure\n        -> response as String\n        theResponse :=: response\n\n      StringResponse() as pure\n        this(String())\n\n      override result()\n        <- rtn as String: theResponse\n\n      default operator ?\n\n    StructuredResponse is StringResponse\n      contentType as String: String()\n\n      StructuredResponse() as pure\n        ->\n          response as String\n          contentType as String\n        super(response)\n        this.contentType :=: contentType\n\n      StructuredResponse() as pure\n        ->\n          response as String\n        this(response, \"text/plain\")\n\n      contentType() as pure\n        <- rtn as String: contentType\n\n      default operator ?\n\n    SimpleProcessor with trait of Processor\n\n      default SimpleProcessor() as pure\n\n      override process()\n        <- response as ProcessingResponse: StringResponse(\"Simple Message\")\n\n    DelegatingProcessor with trait of Processor by proc\n      proc as Processor?\n\n      DelegatingProcessor() as pure\n        -> processorToUse as Processor\n        proc :=? processorToUse\n\n      DelegatingProcessor() as pure\n        this(SimpleProcessor())\n\n      override lowCost() as pure\n        <- rtn as Boolean: false\n\n      default operator ?\n\n    XMLProcessor with trait of Processor\n      override process()\n        <- response as ProcessingResponse: StructuredResponse(\"<tag>Simple Message</tag>\", \"text/xml\")\n      override lowCost() as pure\n        <- rtn as Boolean: false\n\n    //I've used a slightly different layout here and also used named parameters as an example.\n    JSONProcessor with trait of Processor\n      override process()\n        <- response as ProcessingResponse: StructuredResponse(\n          response: `{\"name\": \"John\", \"age\": 31, \"city\": \"New York\"}`,\n          contentType: \"application/json\"\n        )\n\n    ResultBuilder\n\n      build() as dispatcher\n        -> response as ProcessingResponse\n        <- rtn as String: response.result()\n\n      build()\n        -> response as StringResponse\n        <- rtn as String: `\"${response.result()}\"`\n\n      build()\n        -> response as StructuredResponse\n        <- rtn as String: `${response.contentType()} (( ${response.result()} ))`\n\n  defines program\n\n    ProcessorTest\n      stdout <- Stdout()\n\n      processors <- [ SimpleProcessor(), XMLProcessor(), DelegatingProcessor(JSONProcessor()), JSONProcessor()]\n\n      for processor in processors\n        response <- processor.process()\n        stdout.println(ResultBuilder().build(response))","expectedOutput":"\"Simple Message\"\ntext/xml (( <tag>Simple Message</tag> ))\napplication/json (( {\"name\": \"John\", \"age\": 31, \"city\": \"New York\"} ))\napplication/json (( {\"name\": \"John\", \"age\": 31, \"city\": \"New York\"} ))\n","kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"webServices/webServices_addresses.ek9","url":"https://ek9.io/examples/webServices/webServices_addresses.html","title":"A CRUD address service with a mutex-locked repository","code":"#!ek9\ndefines module site.webServices.addresses\n\n  defines type\n    //Just for strong typing - no constraints\n    AddressId as String\n\n  defines record\n    Address\n      id <- AddressId()\n      street <- String()\n      street2 <- String()\n      city <- String()\n      state <- String()\n      zipcode <- String()\n\n      Address()\n        ->\n          id as AddressId\n          street as String\n          street2 as String\n          city as String\n          state as String\n          zipcode as String\n\n        this.id :=: id\n        this.street :=: street\n        this.street2 :=: street2\n        this.city :=: city\n        this.state :=: state\n        this.zipcode :=: zipcode\n\n      Address()\n        -> from as Address\n        this :=: from\n\n      Address()\n        -> from as Optional of Address\n        if from?\n          this :=: from.get()\n\n      //Copy\n      operator :=:\n        -> from as Address\n        id :=: from.id\n        street :=: from.street\n        street2 :=: from.street2\n        city :=: from.city\n        state :=: from.state\n        zipcode :=: from.zipcode\n\n      //Merge only if incoming address parts are set\n      operator :~:\n        -> address as Address\n        if address.street?\n          street :=: address.street\n        if address.street2?\n          street2 :=: address.street2\n        if address.city?\n          city :=: address.city\n        if address.state?\n          state :=: address.state\n        if address.zipcode?\n          zipcode :=: address.zipcode\n\n      override operator ? as pure\n        //street2 is optional and can be omitted\n        <- rtn as Boolean: id? and street? and city? and state? and zipcode?\n\n  defines text for \"en\"\n    AddressToOutputFormat\n\n      toJSON()\n        -> address as Address\n        `{\n\"address\":\n    {\n    \"id\": \"${address.id}\",\n    \"street\": \"${address.street}\",\n    ${optionalJSON(\"street2\", address.street2)}\n    \"city\": \"${address.city}\",\n    \"state\": \"${address.state}\",\n    \"zipcode\": \"${address.zipcode}\"\n    }\n}`\n\n  defines function\n\n    //Used for specific operations to be applied to a set of addresses\n    addressOperation() as abstract\n      ->\n        addresses as AddressAccess\n        address as Address\n\n    //deals with wrapping the operation in the calls to deal with mutex lock.\n    safeOperation()\n      ->\n        lockedAddressSet as MutexLock of AddressSet\n        address as Address\n        operation as addressOperation\n\n      accessKey <- (address, operation) extends MutexKey of AddressSet as function\n          operation(lockedItem, address)\n\n      require lockedAddressSet.enter(accessKey)\n\n    addressFromJson()\n      -> addressInJSONFormat as String\n      <- rtn as Address: Address()\n\n      addressParts <- addressDictionaryFromJSON(addressInJSONFormat)\n      rtn.id: AddressId(addressParts.getOrDefault(\"id\", \"\"))\n      rtn.street: String(addressParts.getOrDefault(\"street\", \"\"))\n      rtn.street2: String(addressParts.getOrDefault(\"street2\", \"\"))\n      rtn.city: String(addressParts.getOrDefault(\"city\", \"\"))\n      rtn.state: String(addressParts.getOrDefault(\"state\", \"\"))\n      rtn.zipcode: String(addressParts.getOrDefault(\"zipcode\", \"\"))\n\n    <?-\n      Until we have a more general JSON parser\n      a bespoke parser is needed for this demonstration\n    -?>\n    addressDictionaryFromJSON()\n      -> json as String\n      <- rtn <- Dict() of (String, String)\n\n      //Just pull out the address bits from within {}'s using a regex\n      extractAddressPartsEx <- /\\{\\s+\"address\":\\s+\\{\\s+([^}]*?)\\s+\\}\\s+\\}/\n      //Now break into lines based on commas\n      addressItems <- json.split(extractAddressPartsEx).getOrDefault(0, \"\").split(/,/)\n      //Map to a dictionary and return.\n      rtn: cat addressItems | map with toDictEntry | collect as Dict of (String, String)\n\n    toDictEntry()\n      -> line as String\n      <- rtn as DictEntry of (String, String)?\n      keyValues <- line.trim().split(/:/)\n      rtn: DictEntry(keyValues.getOrDefault(0, \"\").trim().trim('\"'), keyValues.getOrDefault(length keyValues - 1, \"\").trim().trim('\"'))\n\n    copyAddress()\n      -> from as Address\n      <- to as Address: Address(from)\n\n    wrapInBrackets()\n      -> mainValue as String\n      <- rtn as String: `[ ${mainValue} ]`\n\n    commaSeparated()\n      ->\n        firstPart String\n        secondPart String\n      <-\n        rtn as String: firstPart? and secondPart? <- `${firstPart},${secondPart}` : String()\n\n    addressToJSON()\n      -> address as Address\n      <- addressAsString as String: AddressToOutputFormat(\"en\").toJSON(address)\n\n    addressListToJSON()\n      -> addresses as List of Address\n      <- listAsString as String: cat addresses\n        | map with addressToJSON\n        | join with commaSeparated\n        | map with wrapInBrackets\n        | collect as String\n\n\n    optionalJSON() as pure\n      ->\n        name as String\n        mainValue as String\n      <-\n        rtn as String: mainValue? <- `\"${name}\": \"${mainValue}\",` else String()\n\n  defines trait\n\n    AddressAccess\n\n      hash()\n        <- rtn as String: String()\n\n      hashOfAddress()\n        -> id as AddressId\n        <- rtn as String?\n        require id?\n        rtn: String()\n\n      byId()\n        -> id as AddressId\n        <- rtn as Address?\n\n      listAll()\n        <- rtn as List of Address: List() of Address\n\n      operator +=\n        -> address as Address\n        require address?\n\n      operator -=\n        -> address as Address\n        require address?\n\n      //merge with an existing address\n      operator :~:\n        -> address as Address\n        require address?\n\n      //replace an existing address\n      operator :^:\n        -> address as Address\n        require address?\n\n      operator contains as pure\n        -> addressId as AddressId\n        <- rtn as Boolean: Boolean()\n\n  defines class\n\n    AddressSet with trait of AddressAccess\n      hash as String: Digest().SHA256(GUID())\n      addresses <- Dict() of (AddressId, Address)\n      hashes <- Dict() of (AddressId, String)\n\n      override hash()\n        <- rtn as String: this.hash\n\n      override hashOfAddress()\n        -> id as AddressId\n        <- rtn as String: String(hashes.getOrDefault(id, \"\"))\n\n      override byId()\n        -> id as AddressId\n        <- rtn as Address: Address(addresses.getOrDefault(id, Address()))\n\n      override listAll()\n        <- rtn <- List() of Address\n\n        iter <- addresses.values()\n        cat iter | map with copyAddress > rtn\n\n      private includeAddress()\n        -> address as Address\n\n        copy <- Address(address)\n        addresses += DictEntry(copy.id, copy)\n        hashes += DictEntry(copy.id, Digest().SHA256(addressToJSON(copy)))\n        updateHash()\n\n      private updateHash()\n        hash :=: Digest().SHA256(GUID())\n\n      override operator +=\n        -> address as Address\n        require address?\n\n        if this not contains address\n          includeAddress(address)\n\n      override operator -=\n        -> address as Address\n        require address.id?\n\n        addresses -= address.id\n        hashes -= address.id\n        updateHash()\n\n      override operator :~:\n        -> address as Address\n        require address.id?\n        //We don't assert whole address because it can be partial\n\n        currentAddress <- addresses.getOrDefault(address.id, Address())\n        if currentAddress?\n          //make a new copy and then merge the two.\n          updatedAddress <- Address(currentAddress)\n          updatedAddress :~: address\n          includeAddress(updatedAddress)\n\n      override operator :^:\n        -> address as Address\n        require address?\n\n        if this contains address\n          includeAddress(address)\n\n      operator contains as pure\n        -> address as Address\n        <- rtn as Boolean: this contains address.id\n\n      override operator contains as pure\n        -> addressId as AddressId\n        <- rtn as Boolean: addresses contains addressId\n\n      default operator ?\n\n    //Example of wrapping shared data set in a mutex lock.\n    LockableAddressSet with trait of AddressAccess\n      lockedAddressSet as MutexLock of AddressSet: MutexLock(AddressSet())\n\n      override hash()\n        <- rtn as String: String()\n        accessKey <- (rtn) is MutexKey of AddressSet as function\n          rtn :=: lockedItem.hash()\n\n        require lockedAddressSet.enter(accessKey)\n\n      override hashOfAddress()\n        -> id as AddressId\n        <- rtn as String: String()\n        accessKey <- (id, rtn) is MutexKey of AddressSet as function\n          rtn :=: lockedItem.hashOfAddress(id)\n\n        require lockedAddressSet.enter(accessKey)\n\n      override byId()\n        -> id as AddressId\n        <- rtn as Address: Address()\n        accessKey <- (id, rtn) is MutexKey of AddressSet as function\n          rtn :=: lockedItem.byId(id)\n\n        require lockedAddressSet.enter(accessKey)\n\n      override listAll()\n        <- rtn <- List() of Address\n        accessKey <- (rtn) is MutexKey of AddressSet as function\n          rtn += lockedItem.listAll()\n\n        require lockedAddressSet.enter(accessKey)\n\n      override operator +=\n        -> address as Address\n\n        //You can inline this simple dynamic function if you wish\n        //Also used named parameters\n        safeOperation(\n          lockedAddressSet: lockedAddressSet,\n          address: address,\n          operation: () is addressOperation (addresses += address)\n          )\n\n      override operator -=\n        -> address as Address\n\n        //Or you can inline all on one line.\n        safeOperation(lockedAddressSet, address, () is addressOperation (addresses -= address))\n\n      override operator :~:\n        -> address as Address\n\n        //Or define a dynamic function and pass in as delegate (my preferred way)\n        operation <- () is addressOperation\n          addresses :~: address\n        safeOperation(lockedAddressSet, address, operation)\n\n      override operator :^:\n        -> address as Address\n        operation <- () is addressOperation\n          addresses :^: address\n        safeOperation(lockedAddressSet, address, operation)\n\n      override operator contains as pure\n        -> addressId as AddressId\n        <- rtn as Boolean: false\n        accessKey <- (addressId, rtn) is MutexKey of AddressSet as function\n          rtn :=: lockedItem contains addressId\n\n        require lockedAddressSet.enter(accessKey)\n\n      default operator ?\n\n  defines function\n\n    plainNonCacheableHTTPResponse()\n      <- rtn as HTTPResponse: () with trait of HTTPResponse\n        override cacheControl() as pure\n          <- rtn as String: \"no-store,max-age=0\"\n        override contentType() as pure\n          <- rtn as String: \"text/plain\"\n        override contentLanguage() as pure\n          <- rtn as String: \"en\"\n        default operator ?\n\n    cacheableHTTPResponse()\n      <- rtn as HTTPResponse: () with trait of HTTPResponse\n        override cacheControl() as pure\n          <- rtn as String: \"public,max-age=5,must-revalidate\"\n        override contentType() as pure\n          <- rtn as String: \"application/json\"\n        override contentLanguage() as pure\n          <- rtn as String: \"en\"\n        default operator ?\n\n  defines class\n\n    ByETagHTTPResponse with trait of HTTPResponse by delegate\n      repository as Repository!\n\n      delegate as HTTPResponse?\n      addressId as AddressId?\n      provideContentLocation as Boolean?\n\n      status <- Integer()\n      etagOfAddress <- String()\n\n      default private ByETagHTTPResponse()\n\n      ByETagHTTPResponse()\n        ->\n          addressId as AddressId\n          delegate as HTTPResponse\n          provideContentLocation as Boolean\n        require addressId? and delegate? and provideContentLocation?\n\n        this.addressId: addressId\n        this.provideContentLocation: provideContentLocation\n        this.delegate: delegate\n\n      ByETagHTTPResponse()\n        ->\n          addressId as AddressId\n          delegate as HTTPResponse\n        this(addressId, delegate, true)\n\n      override etag()\n        <- rtn as String: String()\n        //Only call if un-set.\n        etagOfAddress :=? repository.addresses().hashOfAddress(addressId)\n        rtn :=? etagOfAddress\n        status :=? ~etagOfAddress? <- 404 else 200\n\n      status()\n        -> newStatus as Integer\n        status :=: newStatus\n      override status() as pure\n        <- rtn as Integer: status\n      override contentLocation() as pure\n        <- rtn as String: String()\n        httpBadRequest <- 400\n        rtn: status < httpBadRequest and provideContentLocation <- `/addresses/${addressId}` else String()\n      default operator ?\n  <?-\n    REST web service.\n  -?>\n  defines service\n    //The Name of the and the uri it is mapped to\n    Addresses for :/addresses open\n\n      //It is still possible to use dynamic variable capture, like this but see the later code.\n      //It used named variables.\n      byId() as GET for :/{address-id}\n        -> id as String :=: PATH \"address-id\" //required because different name\n        <- response as HTTPResponse?\n\n        addressId <- AddressId(id)\n        delegate <- ByETagHTTPResponse(addressId, cacheableHTTPResponse(), false)\n        response: (addressId, delegate) with trait of HTTPResponse by delegate\n          repository as Repository!\n\n          override content()\n            <- rtn as Bytes: Bytes()\n            httpNotFound <- 404\n            if delegate.status() <> httpNotFound\n              rtn: Bytes().withUtf8(addressToJSON(repository.addresses().byId(addressId)))\n          default operator ?\n\n      //A POST\n      operator += for :/\n        -> request as HTTPRequest :=: REQUEST\n        <- response as HTTPResponse: (\n            request: request,\n            nonCacheable: plainNonCacheableHTTPResponse()\n          ) with trait of HTTPResponse by nonCacheable\n\n            repository as Repository!\n            address as Address: Address()\n            status as Integer: 201\n\n            override content()\n              <- rtn as Bytes: Bytes()\n              address: addressFromJson(request.content().toText(\"utf-8\"))\n              //But the server sets the ID!\n              if address.id?\n                status := 422 //unprocessable entity\n                rtn: Bytes().withUtf8(\"Do not supply ID in Address, server will set this\")\n              else\n                address.id: AddressId(GUID())\n                if ~address?\n                  status := 422 //unprocessable entity\n                else if repository.addresses() contains address.id\n                  status := 409 //conflict\n                else\n                  repository.addresses() += address\n\n            override contentLocation() as pure\n              <- rtn as String: String()\n              httpCreated <- 201\n              rtn: status == httpCreated <- `/addresses/${address.id}` else String()\n            override status() as pure\n              <- rtn as Integer: status\n            default operator ?\n\n      //A DELETE\n      operator -= for :/{id}\n        -> id as String //Assume PATH\n        <- response as HTTPResponse: (\n            addressId: AddressId(id),\n            delegate: ByETagHTTPResponse(\n              AddressId(id),\n              plainNonCacheableHTTPResponse(),\n              false\n            )\n          ) with trait of HTTPResponse by delegate\n\n            repository as Repository!\n\n            override content()\n              <- rtn as Bytes: Bytes()\n              httpNotFound <- 404\n              //Only if the etag was found can we delete it!\n              if delegate.status() <> httpNotFound\n                repository.addresses() -= repository.addresses().byId(addressId)\n                delegate.status(204)\n            default operator ?\n\n      //A PATCH which is a merge\n\n      //Note with dynamic variable capture, you can still do it all one one line if you wish.\n      operator :~: for :/{id}\n        ->\n          id as String //Assume PATH\n          incomingContent as String :=: CONTENT\n        <-\n          response as HTTPResponse: (\n              addressId: AddressId(id),\n              incomingContent: incomingContent,\n              delegate: ByETagHTTPResponse(AddressId(id), plainNonCacheableHTTPResponse())\n            ) trait HTTPResponse by delegate\n            repository as Repository!\n\n            override content()\n              <- rtn as Bytes: Bytes()\n              httpNotFound <- 404\n              if delegate.status() <> httpNotFound\n                address <- addressFromJson(incomingContent)\n                if ~address.id?\n                  delegate.status(422) //unprocessable entity\n                else if address.id <> addressId\n                  delegate.status(400) //the id on the url is not the same as the id in the body content\n                else\n                  repository.addresses() :~: address\n                  delegate.status(204)\n            default operator ?\n\n      //A PUT which is a replace for an existing address\n      //Now the dynamic variable capture allowed multiple lines and various formatting within the ()\n      operator :^: for :/{id}\n        ->\n          id as String //Assume PATH\n          content as String :=: CONTENT\n        <-\n          response as HTTPResponse: (\n                addressId: AddressId(id),\n                incomingContent: content,\n                delegate: ByETagHTTPResponse(AddressId(id), plainNonCacheableHTTPResponse())\n              ) trait HTTPResponse by delegate\n\n            repository as Repository!\n\n            override content()\n              <- rtn as Bytes: Bytes()\n              httpNotFound <- 404\n              if delegate.status() <> httpNotFound\n                address <- addressFromJson(incomingContent)\n                if ~address?\n                  delegate.status(422) //unprocessable entity\n                else if address.id <> addressId\n                  delegate.status(400) //the id on the url is not the same as the mainValue in the body content\n                else\n                  repository.addresses() :^: address\n                  delegate.status(204)\n            default operator ?\n\n      //Note it is now possible to use named parameters in dynamic variable capture\n      //So now, we can do a simpler one liner, define the name of the property and use an expression\n      //to set it up, then use the 'by' on a trait to delegate as much or as little as we want to it.\n      listAll() for :/\n        <- response as HTTPResponse: (\n            cacheable: cacheableHTTPResponse()\n          ) with trait of HTTPResponse by cacheable\n\n          repository as Repository!\n\n          override etag()\n            <- rtn as String: repository.addresses().hash()\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(addressListToJSON(repository.addresses().listAll()))\n          default operator ?\n\n  defines component\n\n    Repository as abstract\n\n      addresses() as pure abstract\n        <- rtn as AddressAccess?\n\n      default operator ?\n\n    InMemoryRepository extends Repository\n      addresses as AddressAccess: LockableAddressSet()\n\n      InMemoryRepository()\n        addresses += Address(id: AddressId(GUID()), street: \"121 Admin Rd.\", street2: String(), city: \"Concord\", state: \"NH\", zipcode: \"03301\")\n        addresses += Address(id: AddressId(GUID()), street: \"67 Paperwork Ave\", street2: String(), city: \"Manchester\", state: \"NH\", zipcode: \"03101\")\n        addresses += Address(id: AddressId(GUID()), street: \"15 Rose St\", street2: \"Apt. B-1\", city: \"Concord\", state: \"NH\", zipcode: \"03301\")\n        addresses += Address(id: AddressId(GUID()), street: \"39 Sole St.\", street2: String(), city: \"Concord\", state: \"NH\", zipcode: \"03301\")\n        addresses += Address(id: AddressId(GUID()), street: \"99 Mountain Rd.\", street2: String(), city: \"Concord\", state: \"NH\", zipcode: \"03301\")\n\n      override addresses() as pure\n        <- rtn as AddressAccess: addresses\n\n      default operator ?\n\n  defines application\n\n    //SERVING wiring: this application registers the REST service, so any program using\n    //it MUST create an HTTP instance. EK9 enforces that both ways — a program wiring this\n    //application without HTTP is E12020 (the service could never receive a request), and\n    //an HTTP program wired to an application with no services is E12021.\n    AccessPoint\n      register InMemoryRepository() as Repository\n      register Addresses()\n\n    //COMPONENT wiring only: no service is registered here, so a plain (non-serving)\n    //program can use it. Splitting the two is the point — conflating them is what\n    //leaves a REST service registered and permanently unreachable.\n    RepositoryOnly\n      register InMemoryRepository() as Repository\n\n  defines program\n\n    //Uses the component-only application: it exercises the repository and exits, so it\n    //must NOT be wired to the service-registering AccessPoint.\n    TestAddressOutput with application of RepositoryOnly\n      //Expect injection\n      repository as Repository!\n\n      stdout <- Stdout()\n\n      address1 <- Address(id: AddressId(GUID()), street: \"121 Admin Rd.\", street2: String(), city: \"Concord\", state: \"NH\", zipcode: \"03301\")\n      address2 <- Address(id: AddressId(GUID()), street: \"15 Rose St\", street2: \"Apt. B-1\", city: \"Concord\", state: \"NH\", zipcode: \"03301\")\n\n      addresses <- [address1, address2]\n\n      iter <- addresses.iterator()\n      //convert contents in iterator to a list\n      theAddresses <- cat iter | collect as List of Address\n      require theAddresses?\n\n      stdout.println(\"Address as JSON\")\n      stdout.println(addressToJSON(address1))\n\n      jsonAddress <- addressFromJson(addressToJSON(address1))\n\n      stdout.println(`Rebuilt address is [${addressToJSON(jsonAddress)}]`)\n\n      stdout.println(\"Now arrays\")\n\n      stdout.println(addressListToJSON(addresses))\n\n      stdout.println(\"Done basics now all addresses\")\n\n      allAddresses <- repository.addresses().listAll()\n\n      stdout.println(`Hash of all addresses is [${repository.addresses().hash()}]`)\n\n      stdout.println(addressListToJSON(allAddresses))\n\n      stdout.println(\"Done!\")\n","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"webServices/webServices_file_server.ek9","url":"https://ek9.io/examples/webServices/webServices_file_server.html","title":"A mini web server serving text files with lastModified","code":"#!ek9\ndefines module site.webServices.fileServer\n\n  defines service\n\n    WebServer for :/website open\n\n      documentRoot() as pure\n        <- rtn as FileSystemPath: FileSystemPath(EnvVars().get(\"DOCUMENT_ROOT\"))\n        if not rtn?\n          throw Exception(\"Invalid Document Root\")\n\n      //Now I've altered the dynamicVariableCapture so it is possible name parameters.\n      //This means we can use expressions in the capture itself and hence can clean up the\n      //expression. This small change means that we can remove dummy creation of responses.\n      file() as GET for :/{fileName}\n        -> fileName as String :=: PATH \"fileName\"\n        <- response as HTTPResponse: (\n          webServer: this,\n          fileName: fileName\n          ) with trait of HTTPResponse\n          lastModified as DateTime: DateTime()\n\n          private lastModifiedOfTextFile() as pure\n            <- rtn as DateTime: DateTime()\n            file <- textFile()\n            if not file.isReadable()\n              Stdout().println(`${file} is not readable`)\n\n            rtn :=? file.lastModified()\n\n          private textFile() as pure\n            <- rtn as TextFile: TextFile(webServer.documentRoot() + FileSystemPath(fileName))\n\n          override lastModified() as pure\n            <- rtn as DateTime: DateTime()\n            lastModified :=? lastModifiedOfTextFile()\n            rtn :=? lastModified\n\n          override cacheControl() as pure\n            <- rtn as String: \"public,max-age=3600,must-revalidate\"\n          override contentType() as pure\n            <- rtn as String: \"text/html\"\n          override contentLanguage() as pure\n            <- rtn as String: \"en\"\n          override status() as pure\n            <- rtn as Integer: lastModified? <- 200:404\n\n          override content()\n            <- rtn as Bytes: Bytes()\n            if lastModified?\n              //Collect the text, then encode ONCE at a visible point. There is deliberately no\n              //Bytes '|' that takes a String: piping text straight into octets would have to\n              //assume an encoding, which is the bug this whole change removes.\n              html <- String()\n              cat textFile().input() > html\n              rtn: Bytes().withUtf8(html)\n          default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"webServices/webServices_static_html.ek9","url":"https://ek9.io/examples/webServices/webServices_static_html.html","title":"A service serving static HTML with an etag","code":"#!ek9\ndefines module site.webServices.staticHtml\n\n  defines text for \"en\"\n\n    WebSite\n      index()\n        `<html>\n<head>\n    <meta charset=\"UTF-8\"/>\n</head>\n<body>\n  <p>Hello, World</p>\n</body>\n</html>`\n\n  defines service\n\n    Site for :/site open\n\n      index() as GET for :/index.html\n        <- response as HTTPResponse: () with trait HTTPResponse\n          //Normally you'd use a component and inject it (i.e. a singleton with web site within)\n          webSite <- WebSite(\"en\")\n          etag as String: String()\n\n          override etag()\n            <- rtn <- String()\n            //Do this (:=?) so the etag is cached and not recalculated each time.\n            //🔑 The body is hashed as OCTETS - no decode, no encoding assumption, and it works\n            //for a binary body. This was an interim .toText(\"utf-8\") round-trip until Digest gained\n            //the Bytes overload; hashing a response body is the textbook digest use.\n            etag :=? Digest().SHA256(content()).toText(\"hex\")\n            rtn :=? etag\n\n          override cacheControl() as pure\n            <- rtn as String: \"public,max-age=3600,must-revalidate\"\n          override contentType() as pure\n            <- rtn as String: \"text/html\"\n          override contentLanguage() as pure\n            <- rtn as String: \"en\"\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(webSite.index())\n          override status() as pure\n            <- rtn as Integer: 200\n          default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation (SiteExamplesCompileTest); each declared expectedOutput is what the program prints when run (SiteExamplesExecutionTest); both in the -Psite gate step","origin":"site"}
{"id":"errors/E01010/bad.ek9","url":"https://ek9.io/errors/E01010.html","title":"E01010: invalid reference naming; module scope name missing","code":"#!ek9\ndefines module error.e01010.bad\n\n  references\n    Circle\n\n  defines function\n\n    unitCircle()\n      <- shape as Circle: Circle(1.0)","expectedOutput":null,"kind":"bad","errors":["E01010"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01010/good.ek9","url":"https://ek9.io/errors/E01010.html","title":"Reference the type with its module name: module::Type","code":"#!ek9\ndefines module error.e01010.good\n\n  references\n    error.e01010.good.shapes::Circle\n\n  defines function\n\n    unitCircle()\n      <- shape as Circle: Circle(1.0)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01010"}
{"id":"errors/E01010/good_shapes.ek9","url":"https://ek9.io/errors/E01010.html","title":"The module that defines Circle","code":"#!ek9\ndefines module error.e01010.good.shapes\n\n  defines class\n\n    Circle\n      radius as Float: 0.0\n\n      Circle()\n        -> initialRadius as Float\n        radius :=: initialRadius\n\n      area()\n        <- rtn as Float: radius * radius * 3.14159\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01010"}
{"id":"errors/E01020/bad.ek9","url":"https://ek9.io/errors/E01020.html","title":"E01020: invalid module name","code":"#!ek9\ndefines module org.ek9.lang\n\n  defines function\n\n    helper()\n      <- rtn as String: \"only the compiler's bootstrap may define this module\"","expectedOutput":null,"kind":"bad","errors":["E01020"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01020/good.ek9","url":"https://ek9.io/errors/E01020.html","title":"Name the module for your own organisation; other org.ek9 names are allowed too","code":"#!ek9\ndefines module error.e01020.good\n\n  defines function\n\n    helper()\n      <- rtn as String: \"a module of your own\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01020"}
{"id":"errors/E01030/bad.ek9","url":"https://ek9.io/errors/E01030.html","title":"E01030: Variable/Function/Type duplicated, likely to lead to confusion","code":"#!ek9\ndefines module error.e01030.bad\n\n  defines class\n\n    Report\n\n      //A property named like the function 'summary' below\n      summary as String: \"monthly\"\n\n      //A method named like the same function\n      summary()\n        <- rtn as String: \"report\"\n\n      default operator ?\n\n  defines function\n\n    summary()\n      <- rtn as String: \"all reports\"","expectedOutput":null,"kind":"bad","errors":["E01030"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01030/good.ek9","url":"https://ek9.io/errors/E01030.html","title":"Give the property, the method and the function names that say what each one is","code":"#!ek9\ndefines module error.e01030.good\n\n  defines class\n\n    Report\n      period as String: \"monthly\"\n\n      describe()\n        <- rtn as String: \"report for \" + period\n\n      default operator ?\n\n  defines function\n\n    reportsSummary()\n      <- rtn as String: \"all reports\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01030"}
{"id":"errors/E01040/bad.ek9","url":"https://ek9.io/errors/E01040.html","title":"E01040: Type/Function name duplicated","code":"#!ek9\ndefines module error.e01040.bad\n\n  defines class\n\n    Customer\n      name as String: \"anonymous\"\n\n      default operator ?\n\n    Customer\n      email as String: \"none\"\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E01040"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01040/good.ek9","url":"https://ek9.io/errors/E01040.html","title":"One type, one name: merge the two, or give the second its own name","code":"#!ek9\ndefines module error.e01040.good\n\n  defines class\n\n    Customer\n      name as String: \"anonymous\"\n\n      default operator ?\n\n    CustomerContact\n      email as String: \"none\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01040"}
{"id":"errors/E01050/bad.ek9","url":"https://ek9.io/errors/E01050.html","title":"E01050: are duplicated values (or are too similar, likely to be confusing)","code":"#!ek9\ndefines module error.e01050.bad\n\n  //Deliberately add in Hearts twice\n  defines type\n\n    CardSuit as\n      Hearts\n      Diamonds\n      Clubs\n      Spades\n      Hearts","expectedOutput":null,"kind":"bad","errors":["E01050"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01050/good.ek9","url":"https://ek9.io/errors/E01050.html","title":"Each enumerated value once, and no two that differ only in case","code":"#!ek9\ndefines module error.e01050.good\n\n  defines type\n\n    CardSuit\n      Hearts\n      Diamonds\n      Clubs\n      Spades","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01050"}
{"id":"errors/E01060/bad.ek9","url":"https://ek9.io/errors/E01060.html","title":"E01060: is a reserved keyword and cannot be used as an identifier","code":"#!ek9\ndefines module error.e01060.bad\n\n  //=== TEST 1: Function names ===\n\n  defines function\n\n    assert()\n      <- result as Boolean: true\n\n    require()\n      <- result as Boolean: true\n\n    assertThrows()\n      <- result as Boolean: true\n\n    assertDoesNotThrow()\n      <- result as Boolean: true\n\n  //=== TEST 2: Method names (inside class scope) ===\n\n  defines class\n\n    BadMethodNames\n      mainValue <- 0\n\n      assert()\n        <- result as Boolean: true\n\n      require()\n        <- result as Boolean: true\n\n      assertThrows()\n        <- result as Boolean: true\n\n      assertDoesNotThrow()\n        <- result as Boolean: true","expectedOutput":null,"kind":"bad","errors":["E01060"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01060/good.ek9","url":"https://ek9.io/errors/E01060.html","title":"Name functions and methods for what they check; assert and require stay statements","code":"#!ek9\ndefines module error.e01060.good\n\n  defines function\n\n    isPositive()\n      -> amount as Integer\n      <- result as Boolean: amount > 0\n\n    checkedTotal()\n      ->\n        first as Integer\n        second as Integer\n      <- result as Integer?\n      require isPositive(first) and isPositive(second)\n      result: first + second\n\n  defines class\n\n    Validator\n      limit as Integer: 100\n\n      withinLimit()\n        -> amount as Integer\n        <- result as Boolean: amount <= limit\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01060"}
{"id":"errors/E01070/bad.ek9","url":"https://ek9.io/errors/E01070.html","title":"E01070: 'break' does not exist in EK9 - use stream pipelines with 'head' or guards","code":"#!ek9\ndefines module error.e01070.bad\n\n  defines function\n\n    firstLongWord()\n      -> words as List of String\n      <- found as String: String()\n      longWordLength <- 5\n      for word in words\n        if length word > longWordLength\n          found: word\n          break","expectedOutput":null,"kind":"bad","errors":["E01070"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01070/good.ek9","url":"https://ek9.io/errors/E01070.html","title":"Stop pulling items with head instead of breaking out","code":"#!ek9\ndefines module error.e01070.good\n\n  defines function\n\n    isLong() as pure\n      -> word as String\n      <- long as Boolean?\n      longWordLength <- 5\n      long: length word > longWordLength\n\n    firstLongWord()\n      -> words as List of String\n      <- found as List of String: List()\n      cat words | filter by isLong | head 1 > found","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01070"}
{"id":"errors/E01070/good_while.ek9","url":"https://ek9.io/errors/E01070.html","title":"Put the stopping condition in the loop condition","code":"#!ek9\ndefines module error.e01070.good.while\n\n  defines function\n\n    countUntilLimit()\n      -> limit as Integer\n      <- counter as Integer: 0\n      while counter < limit\n        counter++","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01070"}
{"id":"errors/E01071/bad.ek9","url":"https://ek9.io/errors/E01071.html","title":"E01071: 'continue' does not exist in EK9 - use stream pipelines with 'filter' or 'skip'","code":"#!ek9\ndefines module error.e01071.bad\n\n  defines function\n\n    //Continue in for loop\n    tryContinueInForLoop()\n      for i in 1 ... 10\n        continue\n\n    //Continue in for loop with condition\n    tryContinueWithCondition()\n      items <- [1, 2, 3, 4, 5]\n      for item in items\n        if item == 3\n          continue\n\n    //Continue in while loop\n    tryContinueInWhileLoop()\n      counter <- 0\n      while counter < 10\n        counter++\n        if counter == 5\n          continue\n\n    //Continue in do-while loop\n    tryContinueInDoWhileLoop()\n      counter <- 0\n      do\n        counter++\n        if counter == 5\n          continue\n      while counter < 10","expectedOutput":null,"kind":"bad","errors":["E01071"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01071/good.ek9","url":"https://ek9.io/errors/E01071.html","title":"Filter out the items you would have skipped with continue","code":"#!ek9\ndefines module error.e01071.good\n\n  defines constant\n    Unlucky <- 13\n\n  defines function\n\n    isLucky()\n      -> item as Integer\n      <- rtn as Boolean: item <> Unlucky\n\n    luckyTotal()\n      -> items as List of Integer\n      <- total as Integer: 0\n      cat items | filter by isLucky > total\n\n    printLucky()\n      -> items as List of Integer\n      stdout <- Stdout()\n      for item in items\n        if isLucky(item)\n          stdout.println($item)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01071"}
{"id":"errors/E01072/bad.ek9","url":"https://ek9.io/errors/E01072.html","title":"E01072: 'return' does not exist in EK9 - declare return values with '<-' and compiler ensures all paths initialize","code":"#!ek9\ndefines module error.e01072.bad\n\n  defines function\n\n    //Return with a value\n    tryReturnWithValue()\n      -> value as String\n      <- result as String: String()\n      return value\n\n    //Return without a value (void return)\n    tryReturnWithoutValue()\n      return\n\n    //Early return in conditional\n    tryEarlyReturn()\n      -> data as String\n      <- result as String: String()\n\n      if not data?\n        return \"\"\n\n    //Return inside a for loop\n    tryReturnInForLoop()\n      -> items as List of Integer\n      <- result as Integer: 0\n\n      for item in items\n        if item > 100\n          return item\n\n    //Return inside a while loop\n    tryReturnInWhileLoop()\n      -> items as List of Integer\n      <- result as Integer: 0\n\n      iter <- items.iterator()\n      while iter.hasNext()\n        item <- iter.next()\n        if item > 100\n          return item","expectedOutput":null,"kind":"bad","errors":["E01072"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01072/good.ek9","url":"https://ek9.io/errors/E01072.html","title":"Declare the returning variable and assign it; the compiler checks every path","code":"#!ek9\ndefines module error.e01072.good\n\n  defines function\n\n    describe()\n      -> name as String\n      <- description as String: \"anonymous\"\n      if name?\n        description: \"named \" + name\n\n    firstOver()\n      ->\n        items as List of Integer\n        threshold as Integer\n      <- found as Integer: Integer()\n      for item in items\n        if item > threshold\n          found :=? item","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01072"}
{"id":"errors/E01073/bad.ek9","url":"https://ek9.io/errors/E01073.html","title":"E01073: 'null' does not exist in EK9 - use tri-state semantics (unset/set) with '?' operator","code":"#!ek9\ndefines module error.e01073.bad\n\n  defines function\n\n    unknownName()\n      <- name as String: String()\n      name: null","expectedOutput":null,"kind":"bad","errors":["E01073"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01073/good.ek9","url":"https://ek9.io/errors/E01073.html","title":"An unset value stands where null would; test it with ?","code":"#!ek9\ndefines module error.e01073.good\n\n  defines function\n\n    unknownName()\n      <- name as String: String()\n\n    greeting()\n      -> name as String\n      <- message as String: \"Hello, guest\"\n      if name?\n        message: \"Hello, \" + name","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01073"}
{"id":"errors/E01074/bad.ek9","url":"https://ek9.io/errors/E01074.html","title":"E01074: semicolons are not needed in EK9 - uses indentation-based syntax like Python","code":"#!ek9\ndefines module error.e01074.bad\n\n  defines function\n\n    trySemicolonAfterAssignment()\n      name <- \"Steve\";\n\n    trySemicolonAfterCall()\n      stdout <- Stdout()\n      stdout.println(\"Hello\");\n\n    trySemicolonAfterIncrement()\n      count <- 0\n      count++;","expectedOutput":null,"kind":"bad","errors":["E01074"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01074/good.ek9","url":"https://ek9.io/errors/E01074.html","title":"Remove the semicolons: one statement per line","code":"#!ek9\ndefines module error.e01074.good\n\n  defines function\n\n    greet()\n      name <- \"Steve\"\n      stdout <- Stdout()\n      stdout.println(\"Hello \" + name)\n\n    countUp()\n      <- count as Integer: 0\n      count++","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01074"}
{"id":"errors/E01075/bad.ek9","url":"https://ek9.io/errors/E01075.html","title":"E01075: 'new' does not exist in EK9 - instantiate types with TypeName() directly","code":"#!ek9\ndefines module error.e01075.bad\n\n  defines function\n\n    //New for simple type instantiation\n    tryNewInstantiation()\n      name <- new String()\n      assert name?\n\n    //New for type with arguments\n    tryNewWithArguments()\n      name <- new String(\"Steve\")\n      assert name?\n\n    //New in assignment to existing variable\n    tryNewInAssignment()\n      name <- String()\n      name: new String(\"Updated\")\n      assert name?","expectedOutput":null,"kind":"bad","errors":["E01075"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01075/good.ek9","url":"https://ek9.io/errors/E01075.html","title":"Call the constructor directly: TypeName(...)","code":"#!ek9\ndefines module error.e01075.good\n\n  defines function\n\n    unsetName()\n      <- name as String: String()\n\n    namedSteve()\n      <- name as String: String(\"Steve\")\n\n    renamed()\n      <- name as String: String()\n      name: String(\"Updated\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01075"}
{"id":"errors/E01076/bad.ek9","url":"https://ek9.io/errors/E01076.html","title":"E01076: 'goto' does not exist in EK9 - use structured control flow","code":"#!ek9\ndefines module error.e01076.bad\n\n  defines constant\n    MaximumAttempts <- 3\n\n  defines function\n\n    process()\n      -> attempts as Integer\n      if attempts > MaximumAttempts\n        goto cleanup","expectedOutput":null,"kind":"bad","errors":["E01076"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01076/good.ek9","url":"https://ek9.io/errors/E01076.html","title":"Use structured control flow: the clean-up goes in a finally block, which always runs","code":"#!ek9\ndefines module error.e01076.good\n\n  defines constant\n    MaximumAttempts <- 3\n\n  defines function\n\n    attempt()\n      -> attempts as Integer\n      <- rtn as String: attempts > MaximumAttempts <- \"gave up\" else \"tried\"\n\n    cleanup()\n      stdout <- Stdout()\n      stdout.println(\"cleaned up\")\n\n    process()\n      -> attempts as Integer\n      stdout <- Stdout()\n      try\n        stdout.println(attempt(attempts))\n      finally\n        cleanup()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01076"}
{"id":"errors/E01077/bad.ek9","url":"https://ek9.io/errors/E01077.html","title":"E01077: 'def' does not exist in EK9 - define functions by name directly","code":"#!ek9\ndefines module error.e01077.bad\n\n  defines function\n\n    def greet(name as String)\n      stdout <- Stdout()\n      stdout.println(\"Hello \" + name)","expectedOutput":null,"kind":"bad","errors":["E01077"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01077/good.ek9","url":"https://ek9.io/errors/E01077.html","title":"Define the function by name in a defines function block; parameters follow '->'","code":"#!ek9\ndefines module error.e01077.good\n\n  defines function\n\n    greet()\n      -> name as String\n      stdout <- Stdout()\n      stdout.println(\"Hello \" + name)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01077"}
{"id":"errors/E01078/bad.ek9","url":"https://ek9.io/errors/E01078.html","title":"E01078: 'elif' does not exist in EK9 - use 'else if' (two words)","code":"#!ek9\ndefines module error.e01078.bad\n\n  defines constant\n    Big <- 10\n    Medium <- 5\n\n  defines function\n\n    describeSize()\n      -> size as Integer\n      stdout <- Stdout()\n      if size > Big\n        stdout.println(\"big\")\n      elif size > Medium\n        stdout.println(\"medium\")","expectedOutput":null,"kind":"bad","errors":["E01078"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01078/good.ek9","url":"https://ek9.io/errors/E01078.html","title":"Write 'else if' as two words","code":"#!ek9\ndefines module error.e01078.good\n\n  defines constant\n    Big <- 10\n    Medium <- 5\n\n  defines function\n\n    describeSize()\n      -> size as Integer\n      stdout <- Stdout()\n      if size > Big\n        stdout.println(\"big\")\n      else if size > Medium\n        stdout.println(\"medium\")\n      else\n        stdout.println(\"small\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01078"}
{"id":"errors/E01079/bad.ek9","url":"https://ek9.io/errors/E01079.html","title":"E01079: 'None' does not exist in EK9 - use tri-state semantics with '?' operator","code":"#!ek9\ndefines module error.e01079.bad\n\n  defines function\n\n    //None in variable assignment\n    tryNoneAssignment()\n      result <- None\n\n    //None in comparison expression\n    tryNoneInComparison()\n      name <- String()\n      isNone <- name == None\n\n    //None assigned to return variable\n    tryNoneAsReturnValue()\n      <- result as String: String()\n      result: None\n\n    //None as function argument\n    helperFunction()\n      -> text as String\n      <- rtn <- true\n\n    tryNoneAsFunctionArgument()\n      helperFunction(None)\n\n    //None used as a variable name\n    tryNoneAsVariable()\n      None <- \"value\"","expectedOutput":null,"kind":"bad","errors":["E01079"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01079/good.ek9","url":"https://ek9.io/errors/E01079.html","title":"An unset value is TypeName(), and '?' asks whether a value is set","code":"#!ek9\ndefines module error.e01079.good\n\n  defines function\n\n    noResultYet()\n      <- result as String: String()\n\n    hasNoName()\n      -> name as String\n      <- rtn as Boolean: not name?\n\n    describe()\n      -> text as String\n      <- rtn as String: text? <- text else \"nothing\"\n\n    describeNothing()\n      <- rtn as String: describe(String())","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01079"}
{"id":"errors/E01080/bad.ek9","url":"https://ek9.io/errors/E01080.html","title":"E01080: 'self' does not exist in EK9 - use 'this' keyword","code":"#!ek9\ndefines module error.e01080.bad\n\n  defines class\n\n    Person\n      name as String: \"Steve\"\n\n      greeting()\n        <- rtn as String: \"I am \" + self.name\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E01080"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01080/good.ek9","url":"https://ek9.io/errors/E01080.html","title":"Use 'this', or just the property name when that is unambiguous","code":"#!ek9\ndefines module error.e01080.good\n\n  defines class\n\n    Person\n      name as String: \"Steve\"\n\n      greeting()\n        <- rtn as String: \"I am \" + this.name\n\n      shortGreeting()\n        <- rtn as String: \"I am \" + name\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01080"}
{"id":"errors/E01081/bad.ek9","url":"https://ek9.io/errors/E01081.html","title":"E01081: Python list comprehensions do not exist in EK9 - use stream pipelines","code":"#!ek9\ndefines module error.e01081.bad\n\n  defines function\n\n    //Simple list comprehension\n    trySimpleListComprehension()\n      numbers <- [1, 2, 3, 4, 5]\n      squares <- [x * x for x in numbers]\n\n    //List comprehension with filter\n    tryListComprehensionWithFilter()\n      numbers <- [1, 2, 3, 4, 5]\n      evens <- [x for x in numbers if x mod 2 == 0]\n\n    //List comprehension identity\n    tryListComprehensionIdentity()\n      items <- [\"a\", \"b\", \"c\"]\n      copy <- [item for item in items]","expectedOutput":null,"kind":"bad","errors":["E01081"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01081/good.ek9","url":"https://ek9.io/errors/E01081.html","title":"Use a stream pipeline: cat, then map or filter, collected into a List","code":"#!ek9\ndefines module error.e01081.good\n\n  defines function\n\n    square()\n      -> number as Integer\n      <- rtn as Integer: number * number\n\n    isEven()\n      -> number as Integer\n      <- rtn as Boolean: number mod 2 == 0\n\n    squares()\n      -> numbers as List of Integer\n      <- rtn as List of Integer: cat numbers | map with square | collect as List of Integer\n\n    evens()\n      -> numbers as List of Integer\n      <- rtn as List of Integer: cat numbers | filter by isEven | collect as List of Integer","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01081"}
{"id":"errors/E01082/bad.ek9","url":"https://ek9.io/errors/E01082.html","title":"E01082: multiple '->' arrows not supported - use indented block for multiple parameters","code":"#!ek9\ndefines module error.e01082.bad\n\n  defines function\n\n    //Two parameters with separate arrows - incorrect\n    badTwoParams()\n      -> param1 as String\n      -> param2 as Integer\n      <- result as String: param1\n\n    //Three parameters with separate arrows - incorrect\n    badThreeParams()\n      -> param1 as String\n      -> param2 as Integer\n      -> param3 as Float\n      <- result as String: param1\n\n    //Correct way - single arrow with indented block\n    goodMultipleParams()\n      ->\n        param1 as String\n        param2 as Integer\n        param3 as Float\n      <- result as String: param1\n\n  defines class\n\n    ExampleClass\n\n      //Method with multiple arrows - incorrect\n      badMethod()\n        -> text as String\n        -> count as Integer\n        <- rtn as Boolean: true\n\n      //Correct method\n      goodMethod()\n        ->\n          text as String\n          count as Integer\n        <- rtn as Boolean: true","expectedOutput":null,"kind":"bad","errors":["E01082"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01082/good.ek9","url":"https://ek9.io/errors/E01082.html","title":"One '->' with the parameters in an indented block","code":"#!ek9\ndefines module error.e01082.good\n\n  defines function\n\n    describe()\n      ->\n        label as String\n        count as Integer\n      <- result as String: `${label} x ${count}`\n\n  defines class\n\n    ExampleClass\n\n      hasLength()\n        ->\n          text as String\n          count as Integer\n        <- rtn as Boolean: length text == count","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01082"}
{"id":"errors/E01083/bad.ek9","url":"https://ek9.io/errors/E01083.html","title":"E01083: multiple '<-' arrows not supported - only one return declaration allowed","code":"#!ek9\ndefines module error.e01083.bad\n\n  defines function\n\n    measure()\n      -> input as String\n      <- text as String: input\n      <- count as Integer: length input","expectedOutput":null,"kind":"bad","errors":["E01083"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01083/good.ek9","url":"https://ek9.io/errors/E01083.html","title":"Return one value: a record that holds both","code":"#!ek9\ndefines module error.e01083.good\n\n  defines record\n\n    Measurement\n      text as String?\n      count as Integer?\n\n      default private Measurement()\n\n      Measurement()\n        ->\n          text as String\n          count as Integer\n        this.text: text\n        this.count: count\n\n      default operator ?\n\n  defines function\n\n    measure()\n      -> input as String\n      <- rtn as Measurement: Measurement(input, length input)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01083"}
{"id":"errors/E01084/bad.ek9","url":"https://ek9.io/errors/E01084.html","title":"E01084: prefix operator used in suffix position - place BEFORE expression","code":"#!ek9\ndefines module error.e01084.bad\n\n  defines function\n\n    firstLetter()\n      -> name as String\n      <- rtn as Character: name #<","expectedOutput":null,"kind":"bad","errors":["E01084"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01084/good.ek9","url":"https://ek9.io/errors/E01084.html","title":"Put the prefix operator before the expression: #< name","code":"#!ek9\ndefines module error.e01084.good\n\n  defines function\n\n    firstLetter()\n      -> name as String\n      <- rtn as Character: #< name","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01084"}
{"id":"errors/E01085/bad.ek9","url":"https://ek9.io/errors/E01085.html","title":"E01085: suffix operator used in prefix position - place AFTER expression","code":"#!ek9\ndefines module error.e01085.bad\n\n  defines function\n\n    isKnown()\n      -> name as String\n      <- rtn as Boolean: ?name","expectedOutput":null,"kind":"bad","errors":["E01085"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01085/good.ek9","url":"https://ek9.io/errors/E01085.html","title":"Put the suffix operator after the expression: name?","code":"#!ek9\ndefines module error.e01085.good\n\n  defines function\n\n    isKnown()\n      -> name as String\n      <- rtn as Boolean: name?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01085"}
{"id":"errors/E01086/bad.ek9","url":"https://ek9.io/errors/E01086.html","title":"E01086: aggregate member out of order - EK9 requires: properties first, then methods, then operators (a bare 'default operator' last)","code":"#!ek9\ndefines module error.e01086.bad\n\n  defines class\n\n    Product\n      name <- String()\n      price <- Float()\n\n      default operator ?\n\n      describe()\n        <- rtn as String: `${name} at ${price}`","expectedOutput":null,"kind":"bad","errors":["E01086"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01086/good.ek9","url":"https://ek9.io/errors/E01086.html","title":"Move the method up: properties, then methods, then operators","code":"#!ek9\ndefines module error.e01086.good\n\n  defines class\n\n    Product\n      name <- String()\n      price <- Float()\n\n      describe()\n        <- rtn as String: `${name} at ${price}`\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01086"}
{"id":"errors/E01086/good_bare_default.ek9","url":"https://ek9.io/errors/E01086.html","title":"A bare 'default operator' is the last item: explicit operators go above it","code":"#!ek9\ndefines module error.e01086.good.bare.default\n\n  defines class\n\n    Product\n      name <- String()\n      price <- Float()\n\n      describe() as pure\n        <- rtn as String: `${name} at ${price}`\n\n      operator $ as pure\n        <- rtn as String: describe()\n\n      default operator","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01086"}
{"id":"errors/E01087/bad.ek9","url":"https://ek9.io/errors/E01087.html","title":"E01087: empty defines block - add at least one type, function, or program definition","code":"#!ek9\ndefines module error.e01087.bad\n\n  defines class\n\n  defines function\n\n  defines trait","expectedOutput":null,"kind":"bad","errors":["E01087"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01087/good.ek9","url":"https://ek9.io/errors/E01087.html","title":"Every defines block declares at least one construct; leave out the ones you do not need","code":"#!ek9\ndefines module error.e01087.good\n\n  defines class\n\n    Counter\n      count as Integer: 0\n\n      increment()\n        count++\n\n      default operator ?\n\n  defines function\n\n    startingCount()\n      <- rtn as Integer: 0","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01087"}
{"id":"errors/E01088/bad.ek9","url":"https://ek9.io/errors/E01088.html","title":"E01088: only one 'defines package' block is permitted per module","code":"#!ek9\ndefines module error.e01088.bad\n\n  defines package\n    description <- \"A library\"\n    version <- 1.0.0-0\n\n  defines package\n    description <- \"A library\"\n    version <- 2.0.0-0","expectedOutput":null,"kind":"bad","errors":["E01088"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01088/good.ek9","url":"https://ek9.io/errors/E01088.html","title":"One defines package block per module, holding every package property","code":"#!ek9\ndefines module error.e01088.good\n\n  defines package\n    description <- \"A library\"\n    version <- 2.0.0-0","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01088"}
{"id":"errors/E01089/bad.ek9","url":"https://ek9.io/errors/E01089.html","title":"E01089: differs only by case from an existing construct (too similar, likely to be confusing)","code":"#!ek9\ndefines module error.e01089.bad\n\n  defines function\n\n    fibonacci()\n      -> count as Integer\n      <- rtn as Integer: count\n\n  defines program\n\n    //Differs only by case from the function 'fibonacci' above\n    Fibonacci()\n      stdout <- Stdout()\n      stdout.println(`${fibonacci(10)}`)","expectedOutput":null,"kind":"bad","errors":["E01089"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01089/good.ek9","url":"https://ek9.io/errors/E01089.html","title":"Give the function and the program names that differ in more than case","code":"#!ek9\ndefines module error.e01089.good\n\n  defines function\n\n    fibonacciSeries()\n      -> count as Integer\n      <- rtn as Integer: count\n\n  defines program\n\n    Fibonacci()\n      stdout <- Stdout()\n      stdout.println(`${fibonacciSeries(10)}`)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01089"}
{"id":"errors/E01090/bad.ek9","url":"https://ek9.io/errors/E01090.html","title":"E01090: is the name of a built-in construct; a second meaning for that name is not allowed","code":"#!ek9\ndefines module error.e01090.bad\n\n  defines constant\n    String <- \"shadow\"\n\n  defines type\n    Colour\n      Red\n      Green\n\n  defines function\n\n    Supplier()\n      <- rtn as String: \"supplied\"\n\n  defines record\n\n    Money\n      amount as Integer: 0\n\n      default operator ?\n\n  defines trait\n\n    Comparator\n      describe() as pure\n        <- rtn as String: \"trait\"\n\n  defines class\n\n    Boolean\n      flag as String: \"x\"\n\n      default operator ?\n\n  defines component\n\n    Iterator\n      describe() as pure\n        <- rtn as String: \"component\"\n\n  defines text for \"en\"\n\n    Exception\n      greeting()\n        \"Hello\"\n\n  defines application\n\n    Networking\n      stdout <- Stdout()\n\n  defines program\n\n    Stdout()\n      value <- \"program\"\n      require value?","expectedOutput":null,"kind":"bad","errors":["E01090"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01090/good.ek9","url":"https://ek9.io/errors/E01090.html","title":"Name each construct for what it is in your domain, never after a built-in","code":"#!ek9\ndefines module error.e01090.good\n\n  defines constant\n    Greeting <- \"shadow\"\n\n  defines type\n    PaintColour\n      Red\n      Green\n\n  defines function\n    nameSupplier()\n      <- rtn as String: \"supplied\"\n\n  defines record\n    Payment\n      amount as Integer: 0\n      default operator ?\n\n  defines trait\n    Describable\n      describe() as pure\n        <- rtn as String: \"trait\"\n\n  defines class\n    Switch\n      label as String: \"x\"\n      default operator ?\n\n  defines component\n    Cursor\n      describe() as pure\n        <- rtn as String: \"component\"\n\n  defines text for \"en\"\n    Messages\n      greeting()\n        \"Hello\"\n\n  defines application\n    Console\n      stdout <- Stdout()\n\n  defines program\n    Printer()\n      stdout <- Stdout()\n      stdout.println(Greeting)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01090"}
{"id":"errors/E01091/bad.ek9","url":"https://ek9.io/errors/E01091.html","title":"E01091: a type parameter name must not resolve to anything; use a conceptual name such as 'T'","code":"#!ek9\ndefines module error.e01091.bad\n\n  defines constant\n    LIMIT <- 10\n\n  defines function\n\n    //A built-in type\n    twice() of type Integer\n      -> item as Integer\n      <- rtn as Integer: item + item\n\n    //This module's own class - declared LATER in the file\n    wrapLater() of type Widget\n      -> item as Widget\n      <- rtn as Widget: item\n\n    //A function of this module\n    passOn() of type helper\n      -> item as helper\n      <- rtn as helper: item\n\n    //A constant of this module\n    limited() of type LIMIT\n      -> item as LIMIT\n      <- rtn as LIMIT: item\n\n    helper()\n      <- rtn as String: \"helper\"\n\n    //Conceptual names are fine - they resolve to nothing\n    fine() of type Element\n      -> item as Element\n      <- rtn as Element: item\n\n  defines class\n\n    //A built-in type, on a generic class\n    Holder of type String\n      default Holder() as pure\n\n      Holder() as pure\n        -> seed as String\n        require seed?\n\n      default operator ?\n\n    //Only the SECOND type parameter resolves\n    Pairing of type (K, Widget)\n      default Pairing() as pure\n\n      Pairing() as pure\n        ->\n          first as K\n          second as Widget\n        require first? and second?\n\n      default operator ?\n\n    Widget\n      label as String: \"widget\"\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E01091"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01091/good.ek9","url":"https://ek9.io/errors/E01091.html","title":"Use conceptual type parameter names that resolve to nothing: T, K, V, Element","code":"#!ek9\ndefines module error.e01091.good\n\n  defines function\n\n    twice() of type T\n      -> item as T\n      <- rtn as List of T: [item, item]\n\n  defines class\n\n    Holder of type T\n      default Holder() as pure\n\n      Holder() as pure\n        -> seed as T\n        require seed?\n\n      default operator ?\n\n    Pairing of type (K, V)\n      default Pairing() as pure\n\n      Pairing() as pure\n        ->\n          first as K\n          second as V\n        require first? and second?\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01091"}
{"id":"errors/E01092/bad.ek9","url":"https://ek9.io/errors/E01092.html","title":"E01092: '?' tests whether a value is set - an assignment target cannot carry it","code":"#!ek9\ndefines module error.e01092.bad\n\n  defines function\n\n    labelled()\n      <- label as String?\n      label? := \"first\"","expectedOutput":null,"kind":"bad","errors":["E01092"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01092/good.ek9","url":"https://ek9.io/errors/E01092.html","title":"Assign to the variable itself; ':=?' assigns only while it has no value","code":"#!ek9\ndefines module error.e01092.good\n\n  defines function\n\n    labelled()\n      <- label as String?\n      label :=? \"first\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01092"}
{"id":"errors/E01093/bad.ek9","url":"https://ek9.io/errors/E01093.html","title":"E01093: a backtick String is never closed - it runs to the end of the file","code":"#!ek9\ndefines module error.e01093.bad\n\n  defines function\n\n    describe()\n      -> count as Integer\n      <- rtn as String: `${count} items\"","expectedOutput":null,"kind":"bad","errors":["E01093"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01093/good.ek9","url":"https://ek9.io/errors/E01093.html","title":"Close a backtick String with a backtick","code":"#!ek9\ndefines module error.e01093.good\n\n  defines function\n\n    describe()\n      -> count as Integer\n      <- rtn as String: `${count} items`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01093"}
{"id":"errors/E01094/bad.ek9","url":"https://ek9.io/errors/E01094.html","title":"E01094: 'close' is not a statement in EK9 - closing is generated: declare 'default operator close' (or write 'operator close' for extra work); a local closes through try or its statement","code":"#!ek9\ndefines module error.e01094.bad\n\n  defines class\n\n    Connection\n      address as String?\n\n      default private Connection()\n\n      Connection()\n        -> address as String\n        this.address: address\n\n      operator close as pure\n        stdout <- Stdout()\n        stdout.println(\"closed \" + address)\n\n      default operator ?\n\n    Holder\n      conn as Connection?\n\n      default private Holder()\n\n      Holder()\n        -> address as String\n        conn: Connection(address)\n\n      operator close as pure\n        close conn\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E01094"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E01094/good.ek9","url":"https://ek9.io/errors/E01094.html","title":"Let the generated close do it: default operator close closes conn","code":"#!ek9\ndefines module error.e01094.good\n\n  defines class\n\n    Connection\n      address as String?\n\n      default private Connection()\n\n      Connection()\n        -> address as String\n        this.address: address\n\n      operator close as pure\n        stdout <- Stdout()\n        stdout.println(\"closed \" + address)\n\n      default operator ?\n\n    Holder\n      conn as Connection?\n\n      default private Holder()\n\n      Holder()\n        -> address as String\n        conn: Connection(address)\n\n      default operator close\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01094"}
{"id":"errors/E01094/good_local.ek9","url":"https://ek9.io/errors/E01094.html","title":"A local closes through its try: declare it as the try's resource","code":"#!ek9\ndefines module error.e01094.good.local\n\n  defines function\n\n    readFirst()\n      -> path as FileSystemPath\n      stdout <- Stdout()\n      try\n        -> input <- TextFile(path).input()\n        stdout.println(input.next())","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E01094"}
{"id":"errors/E02010/bad.ek9","url":"https://ek9.io/errors/E02010.html","title":"E02010: Property/Field duplicated","code":"#!ek9\ndefines module error.e02010.bad\n\n  defines record\n    RBase1 as open\n      prop1 <- String()\n      prop3 <- Date()\n\n      default operator ?\n\n    RExtension1 extends RBase1\n      prop3 <- String()\n\n      default operator ?\n\n    RExtension2 extends RBase1\n      prop1 <- String()\n\n      prop3 <- Time()\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E02010"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E02010/good.ek9","url":"https://ek9.io/errors/E02010.html","title":"An extension adds properties of its own; it never redeclares an inherited one","code":"#!ek9\ndefines module error.e02010.good\n\n  defines record\n\n    RBase1 as open\n      prop1 <- String()\n      prop3 <- Date()\n      default operator ?\n\n    RExtension1 extends RBase1\n      prop4 <- String()\n      default operator ?\n\n    RExtension2 extends RBase1\n      prop5 <- Time()\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E02010"}
{"id":"errors/E02030/bad.ek9","url":"https://ek9.io/errors/E02030.html","title":"E02030: duplicate/ambiguous methods/operations","code":"#!ek9\ndefines module error.e02030.bad\n\n  defines class\n\n    Calculator\n\n      add()\n        ->\n          first as Integer\n          second as Integer\n        <- rtn as Integer: first + second\n\n      //Same name, same parameter types: a duplicate, whatever the body does\n      add()\n        ->\n          first as Integer\n          second as Integer\n        <- rtn as Integer: first + second + 1","expectedOutput":null,"kind":"bad","errors":["E02030"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E02030/good.ek9","url":"https://ek9.io/errors/E02030.html","title":"Give the second method a name that says what it does differently","code":"#!ek9\ndefines module error.e02030.good\n\n  defines class\n\n    Calculator\n\n      add()\n        ->\n          first as Integer\n          second as Integer\n        <- rtn as Integer: first + second\n\n      addWithBonus()\n        ->\n          first as Integer\n          second as Integer\n        <- rtn as Integer: first + second + 1","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E02030"}
{"id":"errors/E02030/good_overload.ek9","url":"https://ek9.io/errors/E02030.html","title":"Or overload it: the same name with different parameter types is a different method","code":"#!ek9\ndefines module error.e02030.good.overload\n\n  defines class\n\n    Calculator\n\n      add()\n        ->\n          first as Integer\n          second as Integer\n        <- rtn as Integer: first + second\n\n      add()\n        ->\n          first as Float\n          second as Float\n        <- rtn as Float: first + second","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E02030"}
{"id":"errors/E02040/bad.ek9","url":"https://ek9.io/errors/E02040.html","title":"E02040: variable name duplicated, resulting in multiple fields of same name","code":"#!ek9\ndefines module error.e02040.bad\n\n  defines function\n\n    discriminator() as abstract\n      -> text as String\n      <- rtn as Boolean?\n\n  defines trait\n\n    Validator\n      validate()\n        -> text as String\n        <- result as Boolean?\n\n  defines program\n\n    CaptureTwice()\n      min <- 10\n      max <- 100\n\n      //The same identifier captured twice\n      longEnough <- (min, min) is discriminator as function\n        rtn: length text > min\n\n      //Two different values captured under one name\n      validator <- (threshold: min, threshold: max) with trait of Validator as class\n        override validate()\n          -> text as String\n          <- result as Boolean: length text > threshold","expectedOutput":null,"kind":"bad","errors":["E02040"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E02040/good.ek9","url":"https://ek9.io/errors/E02040.html","title":"Capture each variable once, and give every named capture its own name","code":"#!ek9\ndefines module error.e02040.good\n\n  defines function\n\n    discriminator() as abstract\n      -> text as String\n      <- rtn as Boolean?\n\n  defines trait\n\n    Validator\n      validate()\n        -> text as String\n        <- result as Boolean?\n\n  defines program\n\n    CaptureOnce()\n      stdout <- Stdout()\n      min <- 10\n      max <- 100\n\n      longEnough <- (min) is discriminator as function\n        rtn: length text > min\n\n      validator <- (minThreshold: min, maxThreshold: max) with trait of Validator as class\n        override validate()\n          -> text as String\n          <- result as Boolean: length text > minThreshold and length text < maxThreshold\n        default operator ?\n\n      stdout.println($longEnough(\"a long enough sentence\"))\n      stdout.println($validator.validate(\"short\"))","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E02040"}
{"id":"errors/E02050/bad.ek9","url":"https://ek9.io/errors/E02050.html","title":"E02050: same trait referenced multiple times","code":"#!ek9\ndefines module error.e02050.bad\n\n  defines trait\n\n    T1\n      method1()\n        <- rtn <- true\n\n    T2\n      method2()\n        <- rtn <- true\n\n    DuplicatedReferences1 with trait of T1, T2, T1\n      method3()\n        <- rtn <- true\n\n    DuplicatedReferences2 with trait of error.e02050.bad::T1, T2, error.e02050.bad::T1\n      method3()\n        <- rtn <- true\n\n    DuplicatedReferences3 with trait of error.e02050.bad::T1, T2, T1\n      method3()\n        <- rtn <- true\n\n    DuplicatedReferences4 with trait of T1, T2, T1, T2, T1\n      method3()\n        <- rtn <- true","expectedOutput":null,"kind":"bad","errors":["E02050"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E02050/good.ek9","url":"https://ek9.io/errors/E02050.html","title":"Name each trait once in the 'with trait of' list","code":"#!ek9\ndefines module error.e02050.good\n\n  defines trait\n\n    T1\n      method1()\n        <- rtn <- true\n\n    T2\n      method2()\n        <- rtn <- true\n\n    BothTraits with trait of T1, T2\n      method3()\n        <- rtn <- true","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E02050"}
{"id":"errors/E02060/bad.ek9","url":"https://ek9.io/errors/E02060.html","title":"E02060: duplicated enumerated value in switch 'case'","code":"#!ek9\ndefines module error.e02060.bad\n\n  defines type\n\n    Direction\n      North\n      South\n      East\n      West\n\n  defines function\n\n    describe()\n      -> direction as Direction\n      <- rtn as String?\n\n      switch direction\n        case Direction.North\n          rtn: \"Going North\"\n        case Direction.South, Direction.East\n          rtn: \"Going South or East\"\n        case Direction.West\n          rtn: \"Going West\"\n        case Direction.North\n          rtn: \"North again\"\n        case Direction.East\n          rtn: \"East is already in the combined case above\"\n        default\n          rtn: \"Unknown\"","expectedOutput":null,"kind":"bad","errors":["E02060"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E02060/good.ek9","url":"https://ek9.io/errors/E02060.html","title":"Each enumerated value in exactly one case; every value covered, and a default","code":"#!ek9\ndefines module error.e02060.good\n\n  defines type\n\n    Direction\n      North\n      South\n      East\n      West\n\n  defines function\n\n    describe()\n      -> direction as Direction\n      <- rtn as String?\n\n      switch direction\n        case Direction.North\n          rtn: \"Going North\"\n        case Direction.South, Direction.East\n          rtn: \"Going South or East\"\n        case Direction.West\n          rtn: \"Going West\"\n        default\n          rtn: \"Unknown\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E02060"}
{"id":"errors/E02070/bad.ek9","url":"https://ek9.io/errors/E02070.html","title":"E02070: PATH is duplicated in terms of structure/naming","code":"#!ek9\ndefines module error.e02070.bad\n\n  defines service\n\n    Resources for :/api open\n\n      resource() as GET for :/{id}\n        -> id as String\n        <- response as HTTPResponse: () with trait of HTTPResponse\n\n      //Same verb, same path structure: {userId} and {id} are both just a path variable\n      user() as GET for :/{userId}\n        -> userId as String\n        <- response as HTTPResponse: () with trait of HTTPResponse","expectedOutput":null,"kind":"bad","errors":["E02070"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E02070/good.ek9","url":"https://ek9.io/errors/E02070.html","title":"Give each operation its own path structure, or a different HTTP verb","code":"#!ek9\ndefines module error.e02070.good\n\n  defines function\n\n    textResponse()\n      -> body as String\n      <- response as HTTPResponse: (body) with trait of HTTPResponse\n        override content()\n          <- rtn as Bytes: Bytes().withUtf8(body)\n        default operator ?\n\n  defines service\n\n    Resources for :/api open\n\n      resource() as GET for :/{id}\n        -> id as String\n        <- response as HTTPResponse: textResponse(id)\n\n      user() as GET for :/users/{userId}\n        -> userId as String\n        <- response as HTTPResponse: textResponse(userId)\n\n      replaceResource() as PUT for :/{id}\n        -> id as String\n        <- response as HTTPResponse: textResponse(\"replaced \" + id)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E02070"}
{"id":"errors/E02080/bad.ek9","url":"https://ek9.io/errors/E02080.html","title":"E02080: use of a delegate and methods of same name","code":"#!ek9\ndefines module error.e02080.bad\n\n  defines function\n\n    NumberSource() as abstract\n      <- rtn as Integer?\n\n  defines class\n\n    Counter\n\n      current()\n        <- rtn as Integer?\n\n        //A delegate named like the method below: which one does next() call?\n        next <- () is NumberSource as function (rtn: 22)\n        rtn: next()\n\n      next()\n        <- rtn as Integer: 1","expectedOutput":null,"kind":"bad","errors":["E02080"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E02080/good.ek9","url":"https://ek9.io/errors/E02080.html","title":"Give the delegate a name no method has, such as one ending in Source or Handler","code":"#!ek9\ndefines module error.e02080.good\n\n  defines function\n\n    NumberSource() as abstract\n      <- rtn as Integer?\n\n  defines class\n\n    Counter\n\n      current()\n        <- rtn as Integer?\n        nextSource <- () is NumberSource as function (rtn: 22)\n        rtn: nextSource() + next()\n\n      next()\n        <- rtn as Integer: 1","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E02080"}
{"id":"errors/E02090/bad.ek9","url":"https://ek9.io/errors/E02090.html","title":"E02090: a listed trait is already a trait of another listed trait or of the super class - it is inherited through that one","code":"#!ek9\ndefines module error.e02090.bad\n\n  defines trait\n\n    Speaker\n      speak()\n        <- rtn as String: \"hello\"\n\n    LoudSpeaker with trait of Speaker\n      shout()\n        <- rtn as String: \"HELLO\"\n\n  defines class\n\n    //LoudSpeaker already has Speaker, so listing Speaker again adds nothing\n    Megaphone with trait of LoudSpeaker, Speaker\n      default operator ?\n\n    Stage with trait of Speaker as open\n      default operator ?\n\n    //The super class Stage already has Speaker, so listing it again adds nothing\n    Podium extends Stage with trait of Speaker\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E02090"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E02090/good.ek9","url":"https://ek9.io/errors/E02090.html","title":"List only the trait that has the other - it brings both; a trait the super class has is not listed again","code":"#!ek9\ndefines module error.e02090.good\n\n  defines trait\n\n    Speaker\n      speak()\n        <- rtn as String: \"hello\"\n\n    LoudSpeaker with trait of Speaker\n      shout()\n        <- rtn as String: \"HELLO\"\n\n  defines class\n\n    //A Megaphone is a LoudSpeaker and so a Speaker too\n    Megaphone with trait of LoudSpeaker\n      default operator ?\n\n    Stage with trait of Speaker as open\n      default operator ?\n\n    //A Podium is a Stage and so a Speaker too\n    Podium extends Stage\n      default operator ?\n\n  defines program\n\n    Announce()\n      stdout <- Stdout()\n      megaphone <- Megaphone()\n      podium <- Podium()\n      stdout.println(`${megaphone.speak()} ${megaphone.shout()} ${podium.speak()}`)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E02090"}
{"id":"errors/E03010/bad.ek9","url":"https://ek9.io/errors/E03010.html","title":"E03010: conflicts with a reference","code":"#!ek9\ndefines module error.e03010.bad\n\n  //A reference says \"use the one from that module\" - even when that module is this one\n  references\n    error.e03010.bad::SharedClass\n    error.e03010.bad::sharedFunction\n\n  defines class\n\n    SharedClass\n      label as String: \"local\"\n      default operator ?\n\n  defines function\n\n    sharedFunction()\n      <- rtn as String: \"local\"","expectedOutput":null,"kind":"bad","errors":["E03010"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E03010/good.ek9","url":"https://ek9.io/errors/E03010.html","title":"Reference the other module's constructs and use them; do not define them again","code":"#!ek9\ndefines module error.e03010.good\n\n  references\n    error.e03010.good.shared::SharedClass\n    error.e03010.good.shared::sharedFunction\n\n  defines function\n\n    describe()\n      <- rtn as String: `${sharedFunction()} ${SharedClass().label()}`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E03010"}
{"id":"errors/E03010/good_local.ek9","url":"https://ek9.io/errors/E03010.html","title":"Or keep your own definitions and drop the references","code":"#!ek9\ndefines module error.e03010.good.local\n\n  defines class\n\n    SharedClass\n      label as String: \"local\"\n      default operator ?\n\n  defines function\n\n    sharedFunction()\n      <- rtn as String: \"local\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E03010"}
{"id":"errors/E03010/good_shared.ek9","url":"https://ek9.io/errors/E03010.html","title":"The module that defines them, once","code":"#!ek9\ndefines module error.e03010.good.shared\n\n  defines class\n\n    SharedClass\n      text as String: \"shared\"\n\n      label()\n        <- rtn as String: text\n\n      default operator ?\n\n  defines function\n\n    sharedFunction()\n      <- rtn as String: \"shared function\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E03010"}
{"id":"errors/E03020/bad.ek9","url":"https://ek9.io/errors/E03020.html","title":"E03020: conflicting references","code":"#!ek9\ndefines module error.e03020.bad\n\n  references\n    org.ek9.lang::Optional\n    org.ek9.lang::Optional\n\n  defines function\n\n    nothingYet()\n      <- rtn as Optional of String: Optional()","expectedOutput":null,"kind":"bad","errors":["E03020"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E03020/good.ek9","url":"https://ek9.io/errors/E03020.html","title":"Reference each construct once","code":"#!ek9\ndefines module error.e03020.good\n\n  references\n    org.ek9.lang::Optional\n\n  defines function\n\n    nothingYet()\n      <- rtn as Optional of String: Optional()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E03020"}
{"id":"errors/E03030/bad.ek9","url":"https://ek9.io/errors/E03030.html","title":"E03030: reference does not resolve","code":"#!ek9\ndefines module error.e03030.bad\n\n  references\n    //No module of that name is in the compile\n    com.nonexistent.module::Helper\n\n    //The module exists, but holds no construct of that name\n    org.ek9.lang::Helper\n\n  defines function\n\n    describe()\n      <- rtn as String: \"nothing to help with\"","expectedOutput":null,"kind":"bad","errors":["E03030"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E03030/good.ek9","url":"https://ek9.io/errors/E03030.html","title":"Reference a construct a module in the compile really defines, spelled exactly","code":"#!ek9\ndefines module error.e03030.good\n\n  references\n    error.e03030.good.utilities::Helper\n\n  defines function\n\n    describe()\n      <- rtn as String: Helper().describe()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E03030"}
{"id":"errors/E03030/good_utilities.ek9","url":"https://ek9.io/errors/E03030.html","title":"The module it comes from must be part of the compile","code":"#!ek9\ndefines module error.e03030.good.utilities\n\n  defines class\n\n    Helper\n      describe()\n        <- rtn as String: \"a helper\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E03030"}
{"id":"errors/E04010/bad.ek9","url":"https://ek9.io/errors/E04010.html","title":"E04010: is not a candidate to be constrained","code":"#!ek9\ndefines module error.e04010.bad\n\n  defines function\n    FunctionA()\n      <- rtn <- true\n\n  defines record\n    R1\n      count <- 0\n      default R1()\n      // 'default operator' gives R1 the ':=:' copy operator so it can be a constrained/alias base\n      // (a constrained type stores an independent copy of its base — E06131 without a copy mechanism).\n      default operator\n\n  defines type\n    Index as Integer\n\n    Name as String\n\n    //We will allow aliasing or typing of other constructs\n    ValidOther as R1\n\n    //But not functions and selected other classes.\n\n    Other1 as FunctionA\n\n    Other2 as Boolean\n\n    Other3 as JSON\n\n    Other4 as Bits\n\n    //A constrained type is a one-level concept: a base type limited to a range of values. Once\n    //constrained it is its own distinct type and CANNOT itself be used as a base — neither further\n    //constrained nor aliased. To make a more specific type, constrain the base type directly.\n    PositiveInt as Integer constrain as\n      > 0\n\n    Other5 as PositiveInt constrain as\n      < 100\n\n    Other6 as PositiveInt","expectedOutput":null,"kind":"bad","errors":["E04010"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E04010/good.ek9","url":"https://ek9.io/errors/E04010.html","title":"Constrain a value type, a record or a class - and constrain the base type directly","code":"#!ek9\ndefines module error.e04010.good\n\n  defines record\n\n    R1\n      count <- 0\n      default R1()\n      default operator\n\n  defines type\n\n    Index as Integer\n\n    Name as String\n\n    ValidOther as R1\n\n    PositiveInt as Integer constrain as\n      > 0\n\n    //Not 'PositiveInt constrain as < 100': constrain Integer itself, once\n    Percentage as Integer constrain as\n      > 0 and < 100","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E04010"}
{"id":"errors/E04020/bad.ek9","url":"https://ek9.io/errors/E04020.html","title":"E04020: result must be String, have the $ operator or can be promoted to String","code":"#!ek9\ndefines module error.e04020.bad\n\n  defines class\n\n    //No '$' operator and no promotion to String\n    Point\n      x as Integer: 0\n      y as Integer: 0\n\n      default operator ?\n\n  defines function\n\n    describe()\n      -> point as Point\n      <- rtn as String: `The point is ${point}`","expectedOutput":null,"kind":"bad","errors":["E04020"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E04020/good.ek9","url":"https://ek9.io/errors/E04020.html","title":"Give the type a '$' operator (default operator $ generates one from its properties)","code":"#!ek9\ndefines module error.e04020.good\n\n  defines class\n\n    Point\n      x as Integer: 0\n      y as Integer: 0\n\n      default operator ?\n      default operator $\n\n  defines function\n\n    describe()\n      -> point as Point\n      <- rtn as String: `The point is ${point}`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E04020"}
{"id":"errors/E04020/good_promotion.ek9","url":"https://ek9.io/errors/E04020.html","title":"Or give the type a promotion to String ('#^')","code":"#!ek9\ndefines module error.e04020.good.promotion\n\n  defines class\n    Point\n      x as Integer: 0\n      y as Integer: 0\n      default operator ?\n\n      //Promoted to a String wherever a String is wanted, an interpolation included\n      operator #^ as pure\n        <- rtn as String: `(${x}, ${y})`\n\n  defines program\n    ShowPoint()\n      stdout <- Stdout()\n      point <- Point()\n      stdout.println(`The point is ${point}`)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E04020"}
{"id":"errors/E04030/bad.ek9","url":"https://ek9.io/errors/E04030.html","title":"E04030: type must be of Exception type","code":"#!ek9\ndefines module error.e04030.bad\n\n  defines function\n\n    validated()\n      -> amount as Integer\n      <- rtn as Integer: amount\n      if amount < 0\n        throw String(\"The amount cannot be negative\")","expectedOutput":null,"kind":"bad","errors":["E04030"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E04030/good.ek9","url":"https://ek9.io/errors/E04030.html","title":"Throw an Exception (or a type that extends it), carrying the message","code":"#!ek9\ndefines module error.e04030.good\n\n  defines function\n\n    validated()\n      -> amount as Integer\n      <- rtn as Integer: amount\n      if amount < 0\n        throw Exception(\"The amount cannot be negative\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E04030"}
{"id":"errors/E04040/bad.ek9","url":"https://ek9.io/errors/E04040.html","title":"E04040: type must be a function or delegate","code":"#!ek9\ndefines module error.e04040.bad\n\n  defines function\n\n    printNumbers()\n      stdout <- Stdout()\n\n      //'call' calls each item it is given, so each item must be a function\n      cat [1, 2] | call > stdout","expectedOutput":null,"kind":"bad","errors":["E04040"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E04040/good.ek9","url":"https://ek9.io/errors/E04040.html","title":"Stream functions into 'call' - or 'map with' a function to transform plain values","code":"#!ek9\ndefines module error.e04040.good\n\n  defines function\n\n    nameSource() as abstract\n      <- rtn as String?\n\n    firstName() is nameSource\n      <- rtn <- \"Steve\"\n\n    lastName() is nameSource\n      <- rtn <- \"Limb\"\n\n    doubled()\n      -> number as Integer\n      <- rtn as Integer: number * 2\n\n    printNames()\n      stdout <- Stdout()\n      cat [firstName, lastName] | call > stdout\n\n    printNumbers()\n      stdout <- Stdout()\n      cat [1, 2] | map with doubled > stdout","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E04040"}
{"id":"errors/E04050/bad.ek9","url":"https://ek9.io/errors/E04050.html","title":"E04050: type must be a simple aggregate/list/dict","code":"#!ek9\ndefines module error.e04050.bad\n\n  defines function\n\n    firstName()\n      //A method call cannot give '<-' its type: the compiler infers it before methods are resolved\n      <- name <- List(\"Steve\").getOrDefault(0, \"\")","expectedOutput":null,"kind":"bad","errors":["E04050"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E04050/good.ek9","url":"https://ek9.io/errors/E04050.html","title":"Declare the type, then assign the expression - or infer only from a literal or constructor","code":"#!ek9\ndefines module error.e04050.good\n\n  defines function\n\n    firstName()\n      <- name as String: List(\"Steve\").getOrDefault(0, \"\")\n\n    emptyCount()\n      <- count <- Integer()\n\n    names()\n      <- rtn <- [\"Steve\", \"Stephen\", \"Steven\"]","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E04050"}
{"id":"errors/E04060/bad.ek9","url":"https://ek9.io/errors/E04060.html","title":"E04060: not an aggregate type","code":"#!ek9\ndefines module error.e04060.bad\n\n  defines function\n\n    greeting()\n      <- rtn as String: \"hello\"\n\n    farewell()\n      <- rtn as String: \"goodbye\"\n\n    sortFunctions()\n      stdout <- Stdout()\n\n      //'sort' orders values by their '<=>' - a function has none\n      cat [greeting, farewell] | sort > stdout","expectedOutput":null,"kind":"bad","errors":["E04060"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E04060/good.ek9","url":"https://ek9.io/errors/E04060.html","title":"Sort values that have a '<=>': call the functions first, then sort what they return","code":"#!ek9\ndefines module error.e04060.good\n\n  defines function\n\n    greeting()\n      <- rtn as String: \"hello\"\n\n    farewell()\n      <- rtn as String: \"goodbye\"\n\n    sortMessages()\n      stdout <- Stdout()\n      cat [greeting, farewell] | call | sort > stdout","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E04060"}
{"id":"errors/E04070/bad.ek9","url":"https://ek9.io/errors/E04070.html","title":"E04070: as it is not 'template/generic' in nature","code":"#!ek9\ndefines module error.e04070.bad\n\n  defines function\n\n    aNonGenericFunction()\n      -> text as String\n      <- rtn as String: text\n\n    badClassUseOfNonGeneric()\n      //Failure 1\n      notActuallyGeneric <- Date() of String\n\n      //Failure 2\n      alsoNotGeneric as Date of String?\n\n    badFunctionUseOfNonGeneric()\n      //Failure 3\n      handler <- () is aNonGenericFunction of Date as function\n\n      //Failure 4\n      functionName as aNonGenericFunction of String?","expectedOutput":null,"kind":"bad","errors":["E04070"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E04070/good.ek9","url":"https://ek9.io/errors/E04070.html","title":"Only a generic type or function takes 'of': use Date and the function as they are","code":"#!ek9\ndefines module error.e04070.good\n\n  defines function\n\n    aNonGenericFunction()\n      -> text as String\n      <- rtn as String: text\n\n    classUse()\n      today <- Date()\n      names <- List() of String\n      require today? and names?\n\n    functionUse()\n      <- rtn as String: aNonGenericFunction(\"plain\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E04070"}
{"id":"errors/E04080/bad.ek9","url":"https://ek9.io/errors/E04080.html","title":"E04080: Template/Generic requires parameterization","code":"#!ek9\ndefines module error.e04080.bad\n\n  defines class\n\n    Box of type T\n      item as T: T()\n\n      default Box()\n\n      Box()\n        -> initial as T\n        item: initial\n\n      default operator ?\n\n  defines function\n\n    unwrap()\n      //'Box' alone is not a type: Box of what?\n      -> container as Box\n      <- rtn as Box: container","expectedOutput":null,"kind":"bad","errors":["E04080"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E04080/good.ek9","url":"https://ek9.io/errors/E04080.html","title":"Parameterise the generic type wherever it is used: Box of String","code":"#!ek9\ndefines module error.e04080.good\n\n  defines class\n\n    Box of type T\n      item as T: T()\n\n      default Box()\n\n      Box()\n        -> initial as T\n        item: initial\n\n      default operator ?\n\n  defines function\n\n    unwrap()\n      -> container as Box of String\n      <- rtn as Box of String: container","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E04080"}
{"id":"errors/E05020/bad.ek9","url":"https://ek9.io/errors/E05020.html","title":"E05020: a circular type/function hierarchy has been used","code":"#!ek9\ndefines module error.e05020.bad\n\n  defines class\n\n    C1 is C3 as open\n      field1 <- \"Steve\"\n\n      default C1()\n\n    C2 is C1 as open\n      field2 <- \"Stephen\"\n\n      default C2()\n\n    C3 is C2 as open\n      field3 <- \"Stephene\"\n\n      default C3()\n\n    CA is CB as open\n      field3 <- \"Stephene\"\n\n      default CA()\n\n    CB is CA as open\n      field4 <- \"Steven\"\n\n      default CB()","expectedOutput":null,"kind":"bad","errors":["E05020"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05020/good.ek9","url":"https://ek9.io/errors/E05020.html","title":"A hierarchy is a tree: pick the one type at the root and extend downwards","code":"#!ek9\ndefines module error.e05020.good\n\n  defines class\n\n    C1 as open\n      field1 <- \"Steve\"\n      default C1()\n      default operator ?\n\n    C2 is C1 as open\n      field2 <- \"Stephen\"\n      default C2()\n      default operator ?\n\n    C3 is C2\n      field3 <- \"Stephene\"\n      default C3()\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05020"}
{"id":"errors/E05030/bad.ek9","url":"https://ek9.io/errors/E05030.html","title":"E05030: not open to be extended","code":"#!ek9\ndefines module error.e05030.bad\n\n  defines class\n\n    Shape\n      describe()\n        <- description as String: \"a shape\"\n\n    Circle extends Shape\n      override describe()\n        <- description as String: \"a circle\"","expectedOutput":null,"kind":"bad","errors":["E05030"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05030/good.ek9","url":"https://ek9.io/errors/E05030.html","title":"Open the type you mean to extend","code":"#!ek9\ndefines module error.e05030.good\n\n  defines class\n\n    Shape as open\n      describe()\n        <- description as String: \"a shape\"\n\n    Circle extends Shape\n      override describe()\n        <- description as String: \"a circle\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05030"}
{"id":"errors/E05040/bad.ek9","url":"https://ek9.io/errors/E05040.html","title":"E05040: 'super' for implicit 'Any' base class is not required","code":"#!ek9\ndefines module error.e05040.bad\n\n  defines class\n\n    Greeter\n      greeting()\n        <- rtn as String: \"hello\"\n\n      describe()\n        <- rtn as String?\n        //Greeter extends nothing explicitly, so its only super is the implicit 'Any'\n        rtn: super.greeting()","expectedOutput":null,"kind":"bad","errors":["E05040"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05040/good.ek9","url":"https://ek9.io/errors/E05040.html","title":"With no explicit super, call the method on this (or just by name)","code":"#!ek9\ndefines module error.e05040.good\n\n  defines class\n\n    Greeter\n      greeting()\n        <- rtn as String: \"hello\"\n\n      describe()\n        <- rtn as String: greeting()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05040"}
{"id":"errors/E05050/bad.ek9","url":"https://ek9.io/errors/E05050.html","title":"E05050: 'this()' and 'super()' must be the first statement in a constructor","code":"#!ek9\ndefines module error.e05050.bad\n\n  defines class\n\n    Base as open\n      label as String: \"base\"\n\n      Base()\n        -> label as String\n        this.label: label\n\n      default operator ?\n\n    Derived extends Base\n      extra as String: \"derived\"\n\n      Derived()\n        -> label as String\n        super(label)\n        //Construction delegates once, first: a second call is not first\n        super(label)\n\n      Derived()\n        ->\n          label as String\n          extra as String\n        this.extra: extra\n        this(label)\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E05050"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05050/good.ek9","url":"https://ek9.io/errors/E05050.html","title":"Call super(...) or this(...) once, as the first statement; other work follows it","code":"#!ek9\ndefines module error.e05050.good\n\n  defines class\n\n    Base as open\n      label as String: \"base\"\n\n      Base()\n        -> label as String\n        this.label: label\n\n      default operator ?\n\n    Derived extends Base\n      extra as String: \"derived\"\n\n      Derived()\n        -> label as String\n        super(label)\n\n      Derived()\n        ->\n          label as String\n          extra as String\n        this(label)\n        this.extra: extra\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05050"}
{"id":"errors/E05060/bad.ek9","url":"https://ek9.io/errors/E05060.html","title":"E05060: 'this()' and 'super()' can only be used in constructors, did you mean 'this.' or 'super.'","code":"#!ek9\ndefines module error.e05060.bad\n\n  defines class\n\n    Counter\n      count as Integer: 0\n\n      increment()\n        count++\n\n      reset()\n        //this() constructs: it is only for the start of a constructor\n        this()\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E05060"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05060/good.ek9","url":"https://ek9.io/errors/E05060.html","title":"Put shared work in a method; constructors delegate with this(...)","code":"#!ek9\ndefines module error.e05060.good\n\n  defines class\n\n    Counter\n      count as Integer: 0\n\n      Counter()\n        reset()\n\n      Counter()\n        -> start as Integer\n        this()\n        count: start\n\n      increment()\n        count++\n\n      reset()\n        count: 0\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05060"}
{"id":"errors/E05070/bad.ek9","url":"https://ek9.io/errors/E05070.html","title":"E05070: inappropriate use of 'this'","code":"#!ek9\ndefines module error.e05070.bad\n\n  defines function\n\n    describe() as pure\n      -> enabled as Boolean\n      <- rtn as String: enabled <- \"on\" else \"off\"\n      //A function is not constructed: this() belongs only in a constructor\n      this()","expectedOutput":null,"kind":"bad","errors":["E05070"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05070/good.ek9","url":"https://ek9.io/errors/E05070.html","title":"Drop the this() call: a function just computes its result","code":"#!ek9\ndefines module error.e05070.good\n\n  defines function\n\n    describe() as pure\n      -> enabled as Boolean\n      <- rtn as String: enabled <- \"on\" else \"off\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05070"}
{"id":"errors/E05080/bad.ek9","url":"https://ek9.io/errors/E05080.html","title":"E05080: inappropriate use of 'super'","code":"#!ek9\ndefines module error.e05080.bad\n\n  defines class\n\n    Base as open\n      label as String: \"base\"\n\n      describe()\n        <- rtn as String: label\n\n      default operator ?\n\n    Derived extends Base\n      extra as String: \"derived\"\n\n      compare()\n        -> other as Base\n        <- rtn as Boolean: other.describe() == describe()\n\n      misuse()\n        <- rtn as Boolean?\n\n        //'super' is not a value: it cannot be held\n        parent <- super\n\n        //Nor passed as an argument\n        rtn: compare(super)\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E05080"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05080/good.ek9","url":"https://ek9.io/errors/E05080.html","title":"Pass 'this' (a Derived is a Base), and use super only to call the parent's method","code":"#!ek9\ndefines module error.e05080.good\n\n  defines class\n\n    Base as open\n      label as String: \"base\"\n\n      describe()\n        <- rtn as String: label\n\n      default operator ?\n\n    Derived extends Base\n      extra as String: \"derived\"\n\n      compare()\n        -> other as Base\n        <- rtn as Boolean: other.describe() == describe()\n\n      override describe()\n        <- rtn as String: `${super.describe()} and ${extra}`\n\n      selfCheck()\n        <- rtn as Boolean: compare(this)\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05080"}
{"id":"errors/E05090/bad.ek9","url":"https://ek9.io/errors/E05090.html","title":"E05090: can be used with :=:, :~:, +=, -=, /= and *=. But not direct assignment","code":"#!ek9\ndefines module error.e05090.bad\n\n  defines class\n\n    C0 as open\n      //Explicitly allow this to be null\n      p0 as Integer?\n\n      default C0()\n\n      //define the copy operator\n      operator :=:\n        -> param as C0\n        this.p0 :=: param.p0\n\n    CC0 extends C0\n      //Explicitly allow this to be null\n      p11 as Integer?\n\n      default CC0()\n\n    C1\n      p1 as String: String()\n\n      C1()\n        -> param as String\n        this.p1: param\n\n      //This is not allowed, developer probably would mean copy the values.\n      C1()\n        -> param as C1\n        this: param\n\n    C2\n      p1 as String: String()\n\n      //This is not allowed, this is always set and so makes no sense.\n      C2()\n        -> param as C2\n        this :=? param\n\n    C2a\n      p1 as String: String()\n\n      //This is not allowed - cannot use direct assignment := to this\n      //Use :=: (copy), :~: (merge), or +=, -=, /=, *= instead\n      C2a()\n        -> param as C2a\n        this := param\n\n    C2b extends C2a\n      p2 as String: String()\n\n      //This is not allowed - cannot use direct assignment := to super\n      C2b()\n        -> param as C2a\n        super := param\n\n    //But these are allowed\n    C3\n      p1 as String: String()\n\n      //Get a full copy of the values from param into this. - i.e. copy the mainValue of param over\n      C3()\n        -> param as C3\n        this :=: param\n\n      //define the copy operator\n      operator :=:\n        -> param as C3\n        this.p1 :=: param.p1\n\n    C4\n      p1 as String: String()\n      p2 as String: \"Steve\"\n      //Get a merge of values from param into this. - i.e. copy the mainValue of param over\n      C4()\n        -> param as C4\n        this :~: param\n\n      //define the merge operator\n      operator :~:\n        -> param as C4\n        //So if p1 or p2 is unset in this, but param p1/p2 is not then it gets merged in as appropriate\n        this.p1 :~: param.p1\n        this.p2 :~: param.p2","expectedOutput":null,"kind":"bad","errors":["E05090"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05090/good.ek9","url":"https://ek9.io/errors/E05090.html","title":"Copy (:=:) or merge (:~:) into this; never assign to this or super","code":"#!ek9\ndefines module error.e05090.good\n\n  defines class\n\n    Account\n      owner as String: String()\n\n      Account()\n        -> owner as String\n        this.owner: owner\n\n      Account()\n        -> other as Account\n        this :=: other\n\n      operator :=:\n        -> other as Account\n        this.owner :=: other.owner\n\n      default operator ?\n\n    Settings\n      theme as String: String()\n      language as String: \"en\"\n\n      Settings()\n        -> defaults as Settings\n        this :~: defaults\n\n      operator :~:\n        -> other as Settings\n        this.theme :~: other.theme\n        this.language :~: other.language\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05090"}
{"id":"errors/E05100/bad.ek9","url":"https://ek9.io/errors/E05100.html","title":"E05100: cannot override anything","code":"#!ek9\ndefines module error.e05100.bad\n\n  defines program\n\n    //A program extends nothing, so there is nothing to override\n    override Report()\n      stdout <- Stdout()\n      stdout.println(\"report\")\n\n  defines service\n\n    Addresses for :/addresses open\n\n      //A service extends nothing either\n      override describe()\n        <- rtn as String: \"addresses\"","expectedOutput":null,"kind":"bad","errors":["E05100"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05100/good.ek9","url":"https://ek9.io/errors/E05100.html","title":"Remove 'override' where there is nothing to extend","code":"#!ek9\ndefines module error.e05100.good\n\n  defines program\n\n    Report()\n      stdout <- Stdout()\n      stdout.println(\"report\")\n\n  defines service\n\n    Addresses for :/addresses open\n\n      describe()\n        <- rtn as String: \"addresses\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05100"}
{"id":"errors/E05110/bad.ek9","url":"https://ek9.io/errors/E05110.html","title":"E05110: does not 'override' any method/operator","code":"#!ek9\ndefines module error.e05110.bad\n\n  defines class\n\n    C1 as open\n      //Private method - hidden from subclasses\n      private someMethod()\n        -> text as String\n        <- rtn as String: text\n\n    //ERROR: Cannot override private method - it's hidden\n    C3u extends C1\n      override someMethod()\n        -> text as String\n        <- rtn as String: `[ ${text} ]`\n\n    //ERROR: Cannot override private method even with protected\n    C4u extends C1\n      override protected someMethod()\n        -> text as String\n        <- rtn as String: `[ ${text} ]`","expectedOutput":null,"kind":"bad","errors":["E05110"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05110/good.ek9","url":"https://ek9.io/errors/E05110.html","title":"A private method is not inherited: a sub-type method of the same name is a new method, without override","code":"#!ek9\ndefines module error.e05110.good\n\n  defines class\n\n    C1 as open\n      private someMethod()\n        -> text as String\n        <- rtn as String: text\n\n    //A NEW method: the private one in C1 is not inherited\n    C3 extends C1\n      someMethod()\n        -> text as String\n        <- rtn as String: `[ ${text} ]`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05110"}
{"id":"errors/E05110/good_overridable.ek9","url":"https://ek9.io/errors/E05110.html","title":"To override it, make the parent method protected (or public) and keep that access","code":"#!ek9\ndefines module error.e05110.good.overridable\n\n  defines class\n\n    C5 as open\n      //Protected or public - can be overridden\n      protected someMethod()\n        -> text as String\n        <- rtn as String: text\n\n    //Now it IS an override\n    OkOverrides1 extends C5\n      override protected someMethod()\n        -> text as String\n        <- rtn as String: `[ ${text} ]`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05110"}
{"id":"errors/E05120/bad.ek9","url":"https://ek9.io/errors/E05120.html","title":"E05120: as it overrides method of same name/signature in hierarchy","code":"#!ek9\ndefines module error.e05120.bad\n\n  defines class\n\n    Shape as open\n      describe()\n        <- description as String: \"a shape\"\n\n    Circle extends Shape\n      describe()\n        <- description as String: \"a circle\"","expectedOutput":null,"kind":"bad","errors":["E05120"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05120/good.ek9","url":"https://ek9.io/errors/E05120.html","title":"Say override when the signature matches the super's","code":"#!ek9\ndefines module error.e05120.good\n\n  defines class\n\n    Shape as open\n      describe()\n        <- description as String: \"a shape\"\n\n    Circle extends Shape\n      override describe()\n        <- description as String: \"a circle\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05120"}
{"id":"errors/E05130/bad.ek9","url":"https://ek9.io/errors/E05130.html","title":"E05130: methods with same signature have different access modifiers","code":"#!ek9\ndefines module error.e05130.bad\n\n  defines class\n\n    C5 as open\n      //Protected method\n      protected someMethod()\n        -> text as String\n        <- rtn as String: text\n\n    //ERROR: Cannot restrict protected to private\n    C6 extends C5\n      private someMethod()\n        -> text as String\n        <- rtn as String: `[ ${text} ]`\n\n    //ERROR: Cannot expand protected to public\n    C7 extends C5\n      someMethod()\n        -> text as String\n        <- rtn as String: `[ ${text} ]`\n\n    C8 as open\n      //Public method (no modifier = public)\n      someMethod()\n        -> text as String\n        <- rtn as String: text\n\n    //ERROR: Cannot restrict public to private\n    C9 extends C8\n      private someMethod()\n        -> text as String\n        <- rtn as String: `[ ${text} ]`\n\n    //ERROR: Cannot restrict public to protected\n    C10 extends C8 as open\n      protected someMethod()\n        -> text as String\n        <- rtn as String: `[ ${text} ]`","expectedOutput":null,"kind":"bad","errors":["E05130"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05130/good.ek9","url":"https://ek9.io/errors/E05130.html","title":"An override keeps the access modifier of the method it overrides","code":"#!ek9\ndefines module error.e05130.good\n\n  defines class\n\n    C5 as open\n      protected someMethod()\n        -> text as String\n        <- rtn as String: text\n\n    //Keep the same access modifier (protected)\n    OkOverrides1 extends C5\n      override protected someMethod()\n        -> text as String\n        <- rtn as String: `[ ${text} ]`\n\n    C8 as open\n      someMethod()\n        -> text as String\n        <- rtn as String: text\n\n    //Keep the same access modifier (public)\n    OkOverrides2 extends C8\n      override someMethod()\n        -> text as String\n        <- rtn as String: `[ ${text} ]`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05130"}
{"id":"errors/E05140/bad.ek9","url":"https://ek9.io/errors/E05140.html","title":"E05140: function signature does not match 'super' function","code":"#!ek9\ndefines module error.e05140.bad\n\n  defines function\n\n    //Base function expecting String parameter\n    Function1() as open\n      -> text as String\n      <- rtn as Boolean: text?\n\n    //Abstract function expecting String parameter\n    AbstractFunction1() as abstract\n      -> text as String\n      <- rtn as Boolean?\n\n    //ERROR: Parameter type mismatch (Integer vs String)\n    InvalidFunction1() is Function1\n      -> count as Integer\n      <- rtn <- true\n\n    //ERROR: Parameter type mismatch (Float vs String)\n    InvalidFunction2() is AbstractFunction1\n      -> amount as Float\n      <- rtn <- true","expectedOutput":null,"kind":"bad","errors":["E05140"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05140/good.ek9","url":"https://ek9.io/errors/E05140.html","title":"A function that extends another takes exactly the same parameters","code":"#!ek9\ndefines module error.e05140.good\n\n  defines function\n\n    Function1() as open\n      -> text as String\n      <- rtn as Boolean: text?\n\n    AbstractFunction1() as abstract\n      -> text as String\n      <- rtn as Boolean?\n\n    //The same signature\n    ValidFunction1() is Function1\n      -> text as String\n      <- rtn as Boolean: text?\n\n    //The same signature - it may stay abstract\n    ValidFunction2() is AbstractFunction1 as abstract\n      -> text as String\n      <- rtn as Boolean?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05140"}
{"id":"errors/E05150/bad.ek9","url":"https://ek9.io/errors/E05150.html","title":"E05150: 'pure' in super requires 'pure' for this definition","code":"#!ek9\ndefines module error.e05150.bad\n\n  defines function\n\n    Measure() as pure abstract\n      -> text as String\n      <- size as Integer?\n\n    WordLength() is Measure\n      -> text as String\n      <- size as Integer: length text","expectedOutput":null,"kind":"bad","errors":["E05150"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05150/good.ek9","url":"https://ek9.io/errors/E05150.html","title":"Keep the purity the super promises","code":"#!ek9\ndefines module error.e05150.good\n\n  defines function\n\n    Measure() as pure abstract\n      -> text as String\n      <- size as Integer?\n\n    WordLength() is Measure as pure\n      -> text as String\n      <- size as Integer: length text","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05150"}
{"id":"errors/E05160/bad.ek9","url":"https://ek9.io/errors/E05160.html","title":"E05160: 'super is not 'pure', requires this definition not to be marked as 'pure'","code":"#!ek9\ndefines module error.e05160.bad\n\n  defines function\n\n    //Super function is NOT pure\n    Function1() as open\n      -> text as String\n      <- rtn as Boolean: text?\n\n    //ERROR: Cannot add purity when super is not pure\n    InvalidFunction6() is Function1 as pure\n      -> text as String\n      <- rtn as Boolean: text?","expectedOutput":null,"kind":"bad","errors":["E05160"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05160/good.ek9","url":"https://ek9.io/errors/E05160.html","title":"Match the super function's purity: not pure when it is not","code":"#!ek9\ndefines module error.e05160.good\n\n  defines function\n\n    Function1() as open\n      -> text as String\n      <- rtn as Boolean: text?\n\n    ValidFunction() is Function1\n      -> text as String\n      <- rtn as Boolean: text?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05160"}
{"id":"errors/E05170/bad.ek9","url":"https://ek9.io/errors/E05170.html","title":"E05170: dispatcher handler must match the purity of the dispatcher entry point ('pure' on both or on neither)","code":"#!ek9\ndefines module error.e05170.bad\n\n  defines class\n\n    BadDispatcher4\n\n      //Dispatcher entry point is PURE\n      process() as pure dispatcher\n        -> input as Any\n        require input?\n\n      //ERROR: Dispatch target is NOT pure\n      process()\n        -> input as Integer\n        require input?\n\n    BadDispatcher4b\n\n      //Dispatcher entry point is NOT pure\n      process() as dispatcher\n        -> input as Any\n        require input?\n\n      //ERROR: Dispatch target is pure\n      process() as pure\n        -> input as Integer\n        require input?","expectedOutput":null,"kind":"bad","errors":["E05170"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05170/good.ek9","url":"https://ek9.io/errors/E05170.html","title":"Give every handler the purity of the dispatcher entry point","code":"#!ek9\ndefines module error.e05170.good\n\n  defines class\n\n    GoodDispatcher\n\n      //Dispatcher entry point is pure\n      process() as pure dispatcher\n        -> input as Any\n        require input?\n\n      //Every handler pure too\n      process() as pure\n        -> input as Integer\n        require input?\n\n      process() as pure\n        -> input as String\n        require input?\n\n    GoodNonPureDispatcher\n\n      //Dispatcher entry point is not pure\n      process() as dispatcher\n        -> input as Any\n        require input?\n\n      //No handler pure either\n      process()\n        -> input as Integer\n        require input?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05170"}
{"id":"errors/E05180/bad.ek9","url":"https://ek9.io/errors/E05180.html","title":"E05180: same method name as dispatcher, but marked private in super - won't be called","code":"#!ek9\ndefines module error.e05180.bad\n\n  defines class\n\n    SomeBaseClass as open\n\n      //PRIVATE method - hidden from subclasses\n      private process()\n        -> input as Integer\n        require input?\n\n    BadDispatcher5 extends SomeBaseClass\n\n      //Dispatcher entry point\n      process() as dispatcher\n        -> input as Any\n        require input?","expectedOutput":null,"kind":"bad","errors":["E05180"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05180/good.ek9","url":"https://ek9.io/errors/E05180.html","title":"Make the handler in the super protected (or public) so the dispatcher can reach it","code":"#!ek9\ndefines module error.e05180.good\n\n  defines class\n\n    SomeBaseClass as open\n\n      //Protected: visible to the dispatcher in the sub-type\n      protected process()\n        -> input as Integer\n        require input?\n\n    GoodDispatcher extends SomeBaseClass\n\n      process() as dispatcher\n        -> input as Any\n        require input?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05180"}
{"id":"errors/E05190/bad.ek9","url":"https://ek9.io/errors/E05190.html","title":"E05190: if any constructor is marked pure, all constructors must be pure","code":"#!ek9\ndefines module error.e05190.bad\n\n  defines class\n\n    Person\n      name as String: String()\n      nickname as String: String()\n\n      default Person()\n\n      Person()\n        -> name as String\n        this.name :=? name\n\n      //One pure constructor makes the others inconsistent\n      Person() as pure\n        ->\n          name as String\n          nickname as String\n        this.name :=? name\n        this.nickname :=? nickname\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E05190"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05190/good.ek9","url":"https://ek9.io/errors/E05190.html","title":"Make every constructor pure (a pure constructor sets properties with :=?)","code":"#!ek9\ndefines module error.e05190.good\n\n  defines class\n\n    Person\n      name as String: String()\n      nickname as String: String()\n\n      default Person() as pure\n\n      Person() as pure\n        -> name as String\n        this.name :=? name\n\n      Person() as pure\n        ->\n          name as String\n          nickname as String\n        this.name :=? name\n        this.nickname :=? nickname\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05190"}
{"id":"errors/E05190/good_none.ek9","url":"https://ek9.io/errors/E05190.html","title":"Or make none of them pure","code":"#!ek9\ndefines module error.e05190.good.none\n\n  defines class\n\n    Person\n      name as String: String()\n      nickname as String: String()\n\n      default Person()\n\n      Person()\n        -> name as String\n        this.name: name\n\n      Person()\n        ->\n          name as String\n          nickname as String\n        this.name: name\n        this.nickname: nickname\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05190"}
{"id":"errors/E05200/bad.ek9","url":"https://ek9.io/errors/E05200.html","title":"E05200: incompatible genus with local constructor use","code":"#!ek9\ndefines module error.e05200.bad\n\n  defines application\n\n    ServiceApplication\n      stdout <- Stdout()\n\n  defines program\n\n    AnotherProgram()\n      stdout <- Stdout()\n      stdout.println(\"another\")\n\n    Launcher()\n      //An application is wired to a program, never constructed\n      app <- ServiceApplication()\n\n      //A program is an entry point the runtime starts, never constructed\n      other <- AnotherProgram()","expectedOutput":null,"kind":"bad","errors":["E05200"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05200/good.ek9","url":"https://ek9.io/errors/E05200.html","title":"Wire the application to a program with 'with application of'; run each program from the command line","code":"#!ek9\ndefines module error.e05200.good\n\n  defines application\n\n    ServiceApplication\n      stdout <- Stdout()\n\n  defines program\n\n    AnotherProgram()\n      stdout <- Stdout()\n      stdout.println(\"another\")\n\n    Launcher() with application of ServiceApplication\n      stdout <- Stdout()\n      stdout.println(\"Starting with ServiceApplication\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05200"}
{"id":"errors/E05210/bad.ek9","url":"https://ek9.io/errors/E05210.html","title":"E05210: dispatcher handler type is unreachable from base dispatch type's hierarchy","code":"#!ek9\ndefines module error.e05210.bad\n\n  defines class\n\n    Shape as abstract\n      draw() as abstract\n\n    Circle is Shape\n      override draw()\n        Stdout().println(\"Circle\")\n\n    Renderer\n\n      render() as dispatcher\n        -> s as Shape\n        s.draw()\n\n      render()\n        -> s as Circle\n        Stdout().println(\"Circle render\")\n\n      render()\n        -> s as Integer\n        Stdout().println($s)","expectedOutput":null,"kind":"bad","errors":["E05210"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05210/good.ek9","url":"https://ek9.io/errors/E05210.html","title":"Give handlers only types the dispatcher's parameter can hold: sub-types of Shape","code":"#!ek9\ndefines module error.e05210.good\n\n  defines class\n\n    Shape as abstract\n      draw() as abstract\n\n    Circle is Shape\n      override draw()\n        Stdout().println(\"Circle\")\n\n    Triangle is Shape\n      override draw()\n        Stdout().println(\"Triangle\")\n\n    Renderer\n\n      render() as dispatcher\n        -> s as Shape\n        s.draw()\n\n      render()\n        -> s as Circle\n        Stdout().println(\"Circle render\")\n\n      render()\n        -> s as Triangle\n        Stdout().println(\"Triangle render\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05210"}
{"id":"errors/E05220/bad.ek9","url":"https://ek9.io/errors/E05220.html","title":"E05220: dispatcher handler return type is not covariant with dispatcher entry point return type","code":"#!ek9\ndefines module error.e05220.bad\n\n  defines class\n\n    Formatter\n\n      format() as dispatcher\n        -> input as Any\n        <- rtn as String: \"unknown\"\n\n      //An Integer is not a String: a handler returns what the dispatcher returns\n      format()\n        -> input as Integer\n        <- rtn as Integer: input","expectedOutput":null,"kind":"bad","errors":["E05220"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05220/good.ek9","url":"https://ek9.io/errors/E05220.html","title":"Return the dispatcher's type (or a sub-type of it) from every handler","code":"#!ek9\ndefines module error.e05220.good\n\n  defines class\n\n    Formatter\n\n      format() as dispatcher\n        -> input as Any\n        <- rtn as String: \"unknown\"\n\n      format()\n        -> input as Integer\n        <- rtn as String: $input","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05220"}
{"id":"errors/E05230/bad.ek9","url":"https://ek9.io/errors/E05230.html","title":"E05230: dispatcher has ambiguous handler resolution for reachable type","code":"#!ek9\ndefines module error.e05230.bad\n\n  defines trait\n\n    Flyable\n      fly()\n        Stdout().println(\"Flying\")\n\n    Swimmable\n      swim()\n        Stdout().println(\"Swimming\")\n\n  defines class\n\n    Animal as abstract\n      speak() as abstract\n\n    Dog is Animal\n      override speak()\n        Stdout().println(\"Woof\")\n\n    Cat is Animal\n      override speak()\n        Stdout().println(\"Meow\")\n\n    <?-\n      Duck implements both Flyable and Swimmable.\n      This means handlers for Flyable and Swimmable both match Duck at equal cost.\n    -?>\n    Duck is Animal with trait of Flyable, Swimmable\n      override speak()\n        Stdout().println(\"Quack\")\n\n    <?-\n      AnimalProcessor has handlers for Flyable and Swimmable but no handler\n      for Duck. Since Duck implements both traits at equal cost (0.10),\n      the dispatcher has ambiguous resolution for Duck.\n    -?>\n    AnimalProcessor\n\n      process() as dispatcher\n        -> a as Animal\n        a.speak()\n\n      process()\n        -> a as Dog\n        a.speak()\n\n      process()\n        -> a as Flyable\n        a.fly()\n\n      process()\n        -> a as Swimmable\n        a.swim()","expectedOutput":null,"kind":"bad","errors":["E05230"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05230/good.ek9","url":"https://ek9.io/errors/E05230.html","title":"Add a handler for the type that matches two handlers equally - here Duck","code":"#!ek9\ndefines module error.e05230.good\n\n  defines trait\n\n    Flyable\n      fly()\n        Stdout().println(\"Flying\")\n\n    Swimmable\n      swim()\n        Stdout().println(\"Swimming\")\n\n  defines class\n\n    Animal as abstract\n      speak() as abstract\n\n    Dog is Animal\n      override speak()\n        Stdout().println(\"Woof\")\n\n    Duck is Animal with trait of Flyable, Swimmable\n      override speak()\n        Stdout().println(\"Quack\")\n\n    AnimalProcessor\n\n      process() as dispatcher\n        -> animal as Animal\n        animal.speak()\n\n      process()\n        -> animal as Dog\n        animal.speak()\n\n      process()\n        -> animal as Flyable\n        animal.fly()\n\n      process()\n        -> animal as Swimmable\n        animal.swim()\n\n      //Duck is both Flyable and Swimmable: this handler says which wins\n      process()\n        -> animal as Duck\n        animal.fly()\n        animal.swim()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05230"}
{"id":"errors/E05230/good_bridge.ek9","url":"https://ek9.io/errors/E05230.html","title":"A bridge trait: the multi-trait type takes ONLY the trait that combines the others","code":"#!ek9\ndefines module error.e05230.good.bridge\n\n  defines trait\n    Flyable\n      fly()\n        Stdout().println(\"Flying\")\n    Swimmable\n      swim()\n        Stdout().println(\"Swimming\")\n    //The bridge: inherits fly() and swim()\n    AmphibiousFlyer with trait of Flyable, Swimmable\n\n  defines class\n    Animal as abstract\n      speak() as abstract\n\n    //Duck takes ONLY the bridge trait, never Flyable or Swimmable directly\n    Duck is Animal with trait of AmphibiousFlyer\n      override speak()\n        Stdout().println(\"Quack\")\n\n    AnimalProcessor\n      process() as dispatcher\n        -> animal as Animal\n        animal.speak()\n      process()\n        -> animal as Flyable\n        animal.fly()\n      process()\n        -> animal as Swimmable\n        animal.swim()\n      //One trait hop from Duck: closer than Flyable or Swimmable (two hops)\n      process()\n        -> animal as AmphibiousFlyer\n        animal.fly()\n        animal.swim()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05230"}
{"id":"errors/E05240/bad.ek9","url":"https://ek9.io/errors/E05240.html","title":"E05240: type is not permitted to extend/implement this sealed type","code":"#!ek9\ndefines module error.e05240.bad\n\n  defines trait\n\n    SealedTrait allow only AllowedClass1, AllowedClass2\n      process() as abstract\n\n  defines class\n\n    AllowedClass1 with trait of SealedTrait\n      override process()\n        content <- \"Allowed 1\"\n        require content?\n\n    AllowedClass2 with trait of SealedTrait\n      override process()\n        content <- \"Allowed 2\"\n        require content?\n\n    NotAllowedClass with trait of SealedTrait\n      override process()\n        content <- \"Not Allowed\"\n        require content?\n\n    AnotherNotAllowedClass with trait of SealedTrait\n      override process()\n        content <- \"Also Not Allowed\"\n        require content?\n\n  defines function\n\n    testDynamic()\n      obj <- () trait of SealedTrait as class\n        override process()\n          content <- \"Dynamic\"\n          require content?\n      require obj?","expectedOutput":null,"kind":"bad","errors":["E05240"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05240/good.ek9","url":"https://ek9.io/errors/E05240.html","title":"Only the types the sealed trait names take it on; any other type uses composition","code":"#!ek9\ndefines module error.e05240.good\n\n  defines trait\n\n    SealedTrait allow only AllowedClass1, AllowedClass2\n      process() as abstract\n\n  defines class\n\n    AllowedClass1 with trait of SealedTrait\n      override process()\n        content <- \"Allowed 1\"\n        require content?\n\n    AllowedClass2 with trait of SealedTrait\n      override process()\n        content <- \"Allowed 2\"\n        require content?\n\n    //Not in the list: it holds an allowed type rather than taking on the trait\n    Composed\n      delegate as AllowedClass1: AllowedClass1()\n\n      process()\n        delegate.process()\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05240"}
{"id":"errors/E05250/bad.ek9","url":"https://ek9.io/errors/E05250.html","title":"E05250: abstract type cannot be in 'allow only' list — only concrete classes are permitted","code":"#!ek9\ndefines module error.e05250.bad\n\n  defines class\n\n    AbstractHelper as abstract\n      doWork() as abstract\n\n    ConcreteWorker\n      doWork()\n        content <- \"Working\"\n        require content?\n\n  defines trait\n\n    Workable allow only AbstractHelper, ConcreteWorker\n      process() as abstract","expectedOutput":null,"kind":"bad","errors":["E05250"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05250/good.ek9","url":"https://ek9.io/errors/E05250.html","title":"List only concrete classes after 'allow only'","code":"#!ek9\ndefines module error.e05250.good\n\n  defines class\n\n    ConcreteWorker with trait of Workable\n      override process()\n        content <- \"Working\"\n        require content?\n\n    OtherWorker with trait of Workable\n      override process()\n        content <- \"Also working\"\n        require content?\n\n  defines trait\n\n    Workable allow only ConcreteWorker, OtherWorker\n      process() as abstract","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05250"}
{"id":"errors/E05260/bad.ek9","url":"https://ek9.io/errors/E05260.html","title":"E05260: dispatcher on sealed type must have handlers for all permitted types","code":"#!ek9\ndefines module error.e05260.bad\n\n  defines trait\n\n    Shape allow only Circle, Square, Triangle\n      area() as abstract\n        <- rtn as Float?\n\n  defines class\n\n    Circle with trait of Shape\n      override area()\n        <- rtn as Float: 3.14\n\n    Square with trait of Shape\n      override area()\n        <- rtn as Float: 1.0\n\n    Triangle with trait of Shape\n      override area()\n        <- rtn as Float: 0.5\n\n    <?-\n      IncompleteProcessor only handles Circle.\n      Missing handlers for Square and Triangle.\n    -?>\n    IncompleteProcessor\n\n      process() as dispatcher\n        -> shape as Shape\n        content <- \"Unknown shape\"\n        require content?\n\n      process()\n        -> circle as Circle\n        content <- \"Circle\"\n        require content?\n\n    <?-\n      CompleteProcessor handles all three types.\n      No error expected — all permitted types are covered.\n    -?>\n    CompleteProcessor\n\n      process() as dispatcher\n        -> shape as Shape\n        content <- \"Unknown shape\"\n        require content?\n\n      process()\n        -> circle as Circle\n        content <- \"Circle\"\n        require content?\n\n      process()\n        -> square as Square\n        content <- \"Square\"\n        require content?\n\n      process()\n        -> triangle as Triangle\n        content <- \"Triangle\"\n        require content?","expectedOutput":null,"kind":"bad","errors":["E05260"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05260/good.ek9","url":"https://ek9.io/errors/E05260.html","title":"Give the dispatcher a handler for every type the sealed trait allows","code":"#!ek9\ndefines module error.e05260.good\n\n  defines trait\n\n    Shape allow only Circle, Square, Triangle\n      area() as abstract\n        <- rtn as Float?\n\n  defines class\n\n    Circle with trait of Shape\n      override area()\n        <- rtn as Float: 3.14\n\n    Square with trait of Shape\n      override area()\n        <- rtn as Float: 1.0\n\n    Triangle with trait of Shape\n      override area()\n        <- rtn as Float: 0.5\n\n    CompleteProcessor\n\n      process() as dispatcher\n        -> shape as Shape\n        <- rtn as String: \"Unknown shape\"\n\n      process()\n        -> circle as Circle\n        <- rtn as String: \"Circle\"\n\n      process()\n        -> square as Square\n        <- rtn as String: \"Square\"\n\n      process()\n        -> triangle as Triangle\n        <- rtn as String: \"Triangle\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05260"}
{"id":"errors/E05270/bad.ek9","url":"https://ek9.io/errors/E05270.html","title":"E05270: a class with 'allow only' must be declared 'as open'","code":"#!ek9\ndefines module error.e05270.bad\n\n  defines class\n\n    //Shape names who may extend it, but is closed: nothing may\n    Shape allow only Circle, Square\n      area()\n        <- rtn as Float: 0.0","expectedOutput":null,"kind":"bad","errors":["E05270"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05270/good.ek9","url":"https://ek9.io/errors/E05270.html","title":"Declare the sealed class 'as open'; 'allow only' then limits who extends it","code":"#!ek9\ndefines module error.e05270.good\n\n  defines class\n\n    Shape allow only Circle, Square as open\n      area()\n        <- rtn as Float: 0.0\n\n    Circle extends Shape\n      override area()\n        <- rtn as Float: 3.14\n\n    Square extends Shape\n      override area()\n        <- rtn as Float: 1.0","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05270"}
{"id":"errors/E05280/bad.ek9","url":"https://ek9.io/errors/E05280.html","title":"E05280: dispatcher handler can never be reached - no concrete type in the program routes to it","code":"#!ek9\ndefines module error.e05280.bad\n\n  defines trait\n\n    <?-\n      Nothing implements this trait, so no value can ever have it.\n    -?>\n    Orphaned\n      describe() as pure\n        <- rtn as String: \"orphaned\"\n\n    <?-\n      Control: Adopted IS implemented by a concrete class below.\n    -?>\n    Adopted\n      describe() as pure\n        <- rtn as String: \"adopted\"\n\n  defines function\n\n    <?-\n      Nothing extends this abstract function. Function conformance in EK9 is nominal, so a\n      matching signature elsewhere would NOT make this reachable.\n    -?>\n    OrphanedFunction() as pure abstract\n      -> inputText as String\n      <- outputText as String?\n\n    <?-\n      Control: ExtendedFunction is concrete and extends AdoptedFunction.\n    -?>\n    AdoptedFunction() as pure abstract\n      -> inputText as String\n      <- outputText as String?\n\n    ExtendedFunction() extends AdoptedFunction as pure\n      -> inputText as String\n      <- outputText as String: inputText\n\n  defines class\n\n    <?-\n      Nothing extends this abstract class.\n    -?>\n    OrphanedBase as abstract\n      default operator ?\n\n    ConcreteAdopter with trait of Adopted\n      default operator ?\n\n    <?-\n      Every handler here is declared against a type with no concrete form, so none can ever be\n      selected. The 'Any' base means these are NOT hierarchy errors - every type is under Any -\n      which is exactly why this needed its own check.\n    -?>\n    UnreachableHandlers\n\n      handle() as dispatcher\n        -> item as Any\n        <- rtn as String: \"unreachable-set fallback\"\n\n      handle()\n        -> item as Orphaned\n        <- rtn as String: \"no concrete type implements Orphaned\"\n\n      handle()\n        -> item as OrphanedBase\n        <- rtn as String: \"nothing extends OrphanedBase\"\n\n      handle()\n        -> item as OrphanedFunction\n        <- rtn as String: \"nothing extends OrphanedFunction\"\n\n      handle()\n        -> item as Supplier of String\n        <- rtn as String: \"nothing in this program conforms to Supplier of String\"\n\n    <?-\n      Control class: every handler below IS reachable, so none of them may report.\n      If this class ever starts reporting, the check has become over-eager.\n    -?>\n    ReachableHandlers\n\n      handle() as dispatcher\n        -> item as Any\n        <- rtn as String: \"reachable-set fallback\"\n\n      handle()\n        -> item as Adopted\n        <- rtn as String: \"ConcreteAdopter implements Adopted\"\n\n      handle()\n        -> item as AdoptedFunction\n        <- rtn as String: \"ExtendedFunction extends AdoptedFunction\"\n\n      handle()\n        -> item as ConcreteAdopter\n        <- rtn as String: \"a concrete type is its own instantiation\"\n\n      handle()\n        -> item as Integer\n        <- rtn as String: \"built-in concrete type\"\n\n    <?-\n      The same rule under a NAMED base. MidAbstract is under Shape, so this is not an E05210\n      hierarchy error - but nothing extends MidAbstract, so the handler is still dead.\n    -?>\n    Shape as open\n      default operator ?\n\n    ConcreteShape extends Shape\n      default operator ?\n\n    MidAbstract extends Shape as abstract\n      default operator ?\n\n    NamedBaseHandlers\n\n      render() as dispatcher\n        -> s as Shape\n        <- rtn as String: \"named-base fallback\"\n\n      render()\n        -> s as ConcreteShape\n        <- rtn as String: \"reachable\"\n\n      render()\n        -> s as MidAbstract\n        <- rtn as String: \"nothing extends MidAbstract\"","expectedOutput":null,"kind":"bad","errors":["E05280"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05280/good.ek9","url":"https://ek9.io/errors/E05280.html","title":"Keep only handlers some concrete type in the program can reach; delete the dead ones","code":"#!ek9\ndefines module error.e05280.good\n\n  defines trait\n\n    Adopted\n      describe() as pure\n        <- rtn as String: \"adopted\"\n\n  defines class\n\n    ConcreteAdopter with trait of Adopted\n      default operator ?\n\n    Shape as open\n      default operator ?\n\n    ConcreteShape extends Shape\n      default operator ?\n\n    ReachableHandlers\n      handle() as dispatcher\n        -> item as Any\n        <- rtn as String: \"fallback\"\n\n      handle()\n        -> item as Adopted\n        <- rtn as String: \"ConcreteAdopter implements Adopted\"\n\n      handle()\n        -> item as Integer\n        <- rtn as String: \"built-in concrete type\"\n\n    NamedBaseHandlers\n      render() as dispatcher\n        -> shape as Shape\n        <- rtn as String: \"named-base fallback\"\n\n      render()\n        -> shape as ConcreteShape\n        <- rtn as String: \"reachable\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05280"}
{"id":"errors/E05290/bad.ek9","url":"https://ek9.io/errors/E05290.html","title":"E05290: parents disagree on 'pure' - one method cannot honour both a pure and a non-pure contract","code":"#!ek9\ndefines module error.e05290.bad\n\n  defines trait\n\n    Strict\n      describe() as pure abstract\n        <- rtn as String?\n\n  defines class\n\n    Base as open\n      describe()\n        <- rtn as String: \"base\"\n\n      default operator ?\n\n    Circle extends Base with trait of Strict\n      override describe()\n        <- rtn as String: \"circle\"\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E05290"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E05290/good.ek9","url":"https://ek9.io/errors/E05290.html","title":"Make the parents agree: here both declare describe() pure, so the override is pure","code":"#!ek9\ndefines module error.e05290.good\n\n  defines trait\n\n    Strict\n      describe() as pure abstract\n        <- rtn as String?\n\n  defines class\n\n    Base as open\n      describe() as pure\n        <- rtn as String: \"base\"\n\n      default operator ?\n\n    Circle extends Base with trait of Strict\n      override describe() as pure\n        <- rtn as String: \"circle\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E05290"}
{"id":"errors/E06010/bad.ek9","url":"https://ek9.io/errors/E06010.html","title":"E06010: type/function is generic but no parameters were supplied","code":"#!ek9\ndefines module error.e06010.bad\n\n  defines function\n\n    <?-\n      Valid uses of built-in generics for comparison.\n    -?>\n    ValidBuiltInGenericUse()\n      stdout <- Stdout()\n\n      validOpt <- Optional(\"Hello\")\n      stdout.println(`opt: ${validOpt}`)\n\n      validOpt2 <- Optional() of String\n      stdout.println(`opt2 set: ${validOpt2?}`)\n\n      validList <- [1, 2, 3]\n      stdout.println(`list: ${validList}`)\n\n    <?-\n      Bare Optional() without type parameters.\n    -?>\n    BareOptionalCall()\n      bareOpt <- Optional()\n\n    <?-\n      Bare List() without type parameters.\n    -?>\n    BareListCall()\n      bareList <- List()\n\n    <?-\n      Bare Result() without type parameters.\n    -?>\n    BareResultCall()\n      bareResult <- Result()","expectedOutput":null,"kind":"bad","errors":["E06010"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06010/good.ek9","url":"https://ek9.io/errors/E06010.html","title":"Say what the generic holds: Optional() of String - or declare the type and let it be the target","code":"#!ek9\ndefines module error.e06010.good\n\n  defines function\n\n    typedCalls()\n      stdout <- Stdout()\n      nothingYet <- Optional() of String\n      names as List of String: List()\n      outcome as Result of (String, Integer): Result()\n      stdout.println(`${nothingYet?} ${length names} ${outcome?}`)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06010"}
{"id":"errors/E06010/good_targets.ek9","url":"https://ek9.io/errors/E06010.html","title":"A bare G() takes its type arguments from a declared target of the same generic","code":"#!ek9\ndefines module error.e06010.good.targets\n\n  defines function\n    echo() of type T\n      -> item as T\n      <- rtn as T: item\n\n  defines class\n    Order\n      lines as List of String: List()\n\n      replaceLines()\n        //A typed declaration, and an assignment to a declared variable\n        names as List of String: List()\n        names := List()\n        //A field through 'this', and a field through another object\n        this.lines := List()\n        other <- Order()\n        other.lines: List()\n        //A generic function's value\n        fn as echo of Integer: echo()\n        lines += names\n        lines += other.lines\n        require fn?\n\n      replaceWhenAccepted()\n        -> accepted as Boolean\n        //A ternary arm and an argument are not targets: write the type arguments there\n        this.lines := accepted <- List() of String else [\"none\"]\n        count <- countOf(List() of String)\n        require count?\n\n      countOf()\n        -> items as List of String\n        <- rtn as Integer: length items\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06010"}
{"id":"errors/E06020/bad.ek9","url":"https://ek9.io/errors/E06020.html","title":"E06020: type/function is generic, but incorrect number of parameters supplied","code":"#!ek9\ndefines module error.e06020.bad\n\n  defines function\n\n    declaredTypes()\n      //List takes one type argument, not two\n      numbers as List of (Integer, Date): List()\n\n      //Dict takes two type arguments: key and value\n      lookup as Dict of (Integer): Dict()\n\n    constructedTypes()\n      numbers <- List() of (Integer, Date)\n\n      lookup <- Dict() of (Integer)","expectedOutput":null,"kind":"bad","errors":["E06020"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06020/good.ek9","url":"https://ek9.io/errors/E06020.html","title":"Give each generic exactly as many type arguments as it declares: List one, Dict two","code":"#!ek9\ndefines module error.e06020.good\n\n  defines function\n\n    declaredTypes()\n      <- rtn as Integer?\n      numbers as List of Integer: List()\n      lookup as Dict of (Integer, String): Dict()\n      rtn: length numbers + length lookup\n\n    constructedTypes()\n      <- rtn as Integer?\n      names <- List() of String\n      dates <- Dict() of (String, Date)\n      rtn: length names + length dates","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06020"}
{"id":"errors/E06030/bad.ek9","url":"https://ek9.io/errors/E06030.html","title":"E06030: type is generic, but for type inference to work; the number of generic and constructor parameters must be the same","code":"#!ek9\ndefines module error.e06030.bad\n\n  defines class\n\n    SomeGenericType of type T\n      aField as T?\n\n      default SomeGenericType()\n\n      SomeGenericType()\n        -> param as T\n        aField :=: param\n\n      //Failure 1\n      //This is not allowed, as it is expected a single parameter will give the compiler\n      //the type to infer for the generic nature of the generic/template class.\n      SomeGenericType()\n        ->\n          param1 as T\n          param2 as T\n        aField :=: param1 + param2","expectedOutput":null,"kind":"bad","errors":["E06030"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06030/good.ek9","url":"https://ek9.io/errors/E06030.html","title":"A generic type has one constructor taking each type parameter once; combine values in a method","code":"#!ek9\ndefines module error.e06030.good\n\n  defines class\n\n    SomeGenericType of type T\n      aField as T: T()\n\n      default SomeGenericType()\n\n      SomeGenericType()\n        -> param as T\n        aField :=: param\n\n      contents()\n        <- rtn as T: aField\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06030"}
{"id":"errors/E06030/good_pair.ek9","url":"https://ek9.io/errors/E06030.html","title":"Two type parameters: the inferring constructor takes one of each, in order","code":"#!ek9\ndefines module error.e06030.good.pair\n\n  defines class\n    Pair of type (K, V)\n      key as K: K()\n      content as V: V()\n\n      default Pair()\n\n      Pair()\n        ->\n          initialKey as K\n          initialContent as V\n        key :=: initialKey\n        content :=: initialContent\n\n      describe()\n        <- rtn as String: `${key}=${content}`\n\n      default operator ?\n\n  defines program\n    ShowPair()\n      stdout <- Stdout()\n      //Pair of (String, Integer) is inferred from the two arguments\n      entry <- Pair(\"answer\", 42)\n      stdout.println(entry.describe())","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06030"}
{"id":"errors/E06040/bad.ek9","url":"https://ek9.io/errors/E06040.html","title":"E06040: a generic type requires 2 constructors, default and inferred type","code":"#!ek9\ndefines module error.e06040.bad\n\n  defines class\n\n    //A generic type needs a no-argument constructor AND one taking each type parameter\n    Box of type T\n      default Box()\n\n      check()\n        -> item as T\n        <- rtn as Boolean: item?","expectedOutput":null,"kind":"bad","errors":["E06040"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06040/good.ek9","url":"https://ek9.io/errors/E06040.html","title":"Declare no constructors and let the compiler make both, or declare both","code":"#!ek9\ndefines module error.e06040.good\n\n  defines class\n\n    AutoBox of type T\n      check()\n        -> item as T\n        <- rtn as Boolean: item?\n\n    ManualBox of type T\n      default ManualBox()\n\n      default ManualBox()\n        -> item as T\n\n      check()\n        -> item as T\n        <- rtn as Boolean: item?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06040"}
{"id":"errors/E06050/bad.ek9","url":"https://ek9.io/errors/E06050.html","title":"E06050: a generic type requires correct constructor argument to match parametric types (and order)","code":"#!ek9\ndefines module error.e06050.bad\n\n  defines class\n\n    Pair of type (S, T)\n\n      default Pair()\n\n      default Pair()\n        ->\n          //The constructor's parameters follow the type parameters in order: S, then T\n          first as T\n          second as T\n\n      check()\n        -> item as T\n        <- rtn as Boolean: item?","expectedOutput":null,"kind":"bad","errors":["E06050"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06050/good.ek9","url":"https://ek9.io/errors/E06050.html","title":"Take each type parameter once, in the order they are declared: (S, T)","code":"#!ek9\ndefines module error.e06050.good\n\n  defines class\n\n    Pair of type (S, T)\n\n      default Pair()\n\n      default Pair()\n        ->\n          first as S\n          second as T\n\n      check()\n        -> item as T\n        <- rtn as Boolean: item?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06050"}
{"id":"errors/E06060/bad.ek9","url":"https://ek9.io/errors/E06060.html","title":"E06060: a generic type does not support private or protected constructors","code":"#!ek9\ndefines module error.e06060.bad\n\n  defines class\n\n    Box of type T\n      //Protected is never allowed\n      default protected Box()\n\n      //Private is allowed only on the no-argument constructor\n      default private Box()\n        -> item as T\n\n      check()\n        -> item as T\n        <- rtn as Boolean: item?","expectedOutput":null,"kind":"bad","errors":["E06060"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06060/good.ek9","url":"https://ek9.io/errors/E06060.html","title":"Leave a generic type's constructors public (no access modifier)","code":"#!ek9\ndefines module error.e06060.good\n\n  defines class\n\n    Box of type T\n      default Box()\n\n      default Box()\n        -> item as T\n\n      check()\n        -> item as T\n        <- rtn as Boolean: item?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06060"}
{"id":"errors/E06060/good_private.ek9","url":"https://ek9.io/errors/E06060.html","title":"The no-argument default constructor may be private, when T properties have no initial value","code":"#!ek9\ndefines module error.e06060.good.private\n\n  defines class\n\n    Holder of type T\n      item as T?\n\n      default private Holder()\n\n      Holder()\n        -> item as T\n        this.item: item\n\n      contents()\n        <- rtn as T: item\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06060"}
{"id":"errors/E06070/bad.ek9","url":"https://ek9.io/errors/E06070.html","title":"E06070: type inference is not supported within generic/template type/functions","code":"#!ek9\ndefines module error.e06070.bad\n\n  defines class\n\n    Box of type T\n      item as T: T()\n\n      default Box()\n\n      Box()\n        -> initial as T\n        item: initial\n\n      //Inside a generic type, every declaration states its type\n      count()\n        <- rtn as Integer?\n        start <- 1\n        rtn: start\n\n      check()\n        -> candidate as T\n        <- rtn <- candidate?\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E06070"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06070/good.ek9","url":"https://ek9.io/errors/E06070.html","title":"Declare the type explicitly inside a generic type or function","code":"#!ek9\ndefines module error.e06070.good\n\n  defines class\n\n    Box of type T\n      item as T: T()\n\n      default Box()\n\n      Box()\n        -> initial as T\n        item: initial\n\n      count()\n        <- rtn as Integer?\n        start as Integer: 1\n        rtn: start\n\n      check()\n        -> candidate as T\n        <- rtn as Boolean: candidate?\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06070"}
{"id":"errors/E06080/bad.ek9","url":"https://ek9.io/errors/E06080.html","title":"E06080: the constraining type with a generic/template cannot be a function","code":"#!ek9\ndefines module error.e06080.bad\n\n  defines function\n\n    checkFunction()\n      -> amount as Integer\n      <- rtn as Boolean: amount?\n\n    abstractCheck() as abstract\n      -> amount as Integer\n      <- rtn as Boolean?\n\n  defines class\n\n    //A type parameter can be constrained by a type, never by a function\n    Checked of type T constrain by checkFunction\n      default Checked()\n\n      Checked()\n        -> item as T\n        require item?\n\n      check()\n        -> item as T\n        <- rtn as Boolean: item?\n\n    AlsoChecked of type T constrain by abstractCheck\n      default AlsoChecked()\n\n      AlsoChecked()\n        -> item as T\n        require item?\n\n      check()\n        -> item as T\n        <- rtn as Boolean: item?","expectedOutput":null,"kind":"bad","errors":["E06080"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06080/good.ek9","url":"https://ek9.io/errors/E06080.html","title":"Constrain the type parameter by a trait, class or component instead","code":"#!ek9\ndefines module error.e06080.good\n\n  defines trait\n\n    Checkable\n      check()\n        -> text as String\n        <- rtn as Boolean: text?\n\n  defines component\n\n    Checker as open\n      check()\n        -> text as String\n        <- rtn as Boolean: text?\n\n  defines class\n\n    ByTrait of type T constrain by Checkable\n      default ByTrait()\n\n      ByTrait()\n        -> item as T\n        require item?\n\n      check()\n        -> item as T\n        <- rtn as Boolean: item?\n\n    ByComponent of type T constrain by Checker\n      default ByComponent()\n\n      ByComponent()\n        -> item as T\n        require item?\n\n      check()\n        -> item as T\n        <- rtn as Boolean: item?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06080"}
{"id":"errors/E06090/bad.ek9","url":"https://ek9.io/errors/E06090.html","title":"E06090: a named dynamic class cannot be used within a generic type/function","code":"#!ek9\ndefines module error.e06090.bad\n\n  defines trait\n\n    Processor\n      process()\n        -> text as String\n        <- rtn as String: text\n\n  defines class\n\n    Container of type T\n\n      handle()\n        -> item as T\n        <- rtn as String?\n        require item?\n\n        //A NAMED dynamic class would be one class shared by every 'Container of X'\n        processor as Processor: NamedProcessor() with trait of Processor as class\n          override process()\n            -> text as String\n            <- rtn as String: `processed: ${text}`\n\n        rtn: processor.process(\"item\")","expectedOutput":null,"kind":"bad","errors":["E06090"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06090/good.ek9","url":"https://ek9.io/errors/E06090.html","title":"Leave the dynamic class anonymous inside a generic type or function","code":"#!ek9\ndefines module error.e06090.good\n\n  defines trait\n\n    Processor\n      process()\n        -> text as String\n        <- rtn as String: text\n\n  defines class\n\n    Container of type T\n\n      handle()\n        -> item as T\n        <- rtn as String?\n        require item?\n\n        processor as Processor: () with trait of Processor as class\n          override process()\n            -> text as String\n            <- rtn as String: `processed: ${text}`\n\n        rtn: processor.process(\"item\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06090"}
{"id":"errors/E06100/bad.ek9","url":"https://ek9.io/errors/E06100.html","title":"E06100: implementation must be provided for generic function","code":"#!ek9\ndefines module error.e06100.bad\n\n  defines function\n\n    Transformer() of type T as abstract\n      -> input as T\n      <- result as T?\n\n  defines program\n\n    Transform()\n      stdout <- Stdout()\n\n      //A dynamic function of an abstract generic function must give the body\n      transformer <- () is Transformer of String as function\n\n      stdout.println(transformer(\"text\"))","expectedOutput":null,"kind":"bad","errors":["E06100"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06100/good.ek9","url":"https://ek9.io/errors/E06100.html","title":"Give the dynamic function its body; it takes the parameters and return of Transformer of String","code":"#!ek9\ndefines module error.e06100.good\n\n  defines function\n\n    Transformer() of type T as abstract\n      -> input as T\n      <- result as T?\n\n  defines program\n\n    Transform()\n      stdout <- Stdout()\n\n      transformer <- () is Transformer of String as function\n        result: `${input} processed`\n\n      stdout.println(transformer(\"text\"))","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06100"}
{"id":"errors/E06110/bad.ek9","url":"https://ek9.io/errors/E06110.html","title":"E06110: use of a constructor in a generic/template that uses a function is not supported","code":"#!ek9\ndefines module error.e06110.bad\n\n  defines constant\n    DrinkingAge <- 21\n\n  defines function\n\n    isAdult()\n      -> age as Integer\n      <- rtn as Boolean: age >= DrinkingAge\n\n  defines class\n\n    Factory of type T\n\n      default Factory()\n\n      default Factory()\n        -> item as T\n\n      //Assumes T can be constructed - a function cannot\n      fresh()\n        <- rtn as T: T()\n\n  defines function\n\n    useFactory()\n      factory <- Factory() of isAdult\n      require factory?","expectedOutput":null,"kind":"bad","errors":["E06110"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06110/good.ek9","url":"https://ek9.io/errors/E06110.html","title":"Parameterise with a type that can be constructed, or use a generic that does not construct T","code":"#!ek9\ndefines module error.e06110.good\n\n  defines constant\n    DrinkingAge <- 21\n\n  defines function\n\n    isAdult()\n      -> age as Integer\n      <- rtn as Boolean: age >= DrinkingAge\n\n  defines class\n\n    Factory of type T\n\n      default Factory()\n\n      default Factory()\n        -> item as T\n\n      fresh()\n        <- rtn as T: T()\n\n    Pair of type T\n\n      default Pair()\n\n      default Pair()\n        -> item as T\n\n      bothSet()\n        ->\n          first as T\n          second as T\n        <- rtn as Boolean: first? and second?\n\n  defines function\n\n    useBoth()\n      <- rtn as Boolean?\n      factory <- Factory() of String\n      pair <- Pair() of isAdult\n      rtn: factory.fresh()? and pair.bothSet(isAdult, isAdult)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06110"}
{"id":"errors/E06120/bad.ek9","url":"https://ek9.io/errors/E06120.html","title":"E06120: functions can be used in generics/templates but only '?' is supported","code":"#!ek9\ndefines module error.e06120.bad\n\n  defines function\n\n    validator() as abstract\n      -> text as String\n      <- rtn as Boolean?\n\n    //An unconstrained generic function that adds its arguments\n    combined() of type T\n      ->\n        first as T\n        second as T\n      <- rtn as T: first + second\n\n    useWithAFunction()\n      //A function has '?' and nothing else - it cannot be added\n      combiner <- combined() of validator\n      require combiner?","expectedOutput":null,"kind":"bad","errors":["E06120"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06120/good.ek9","url":"https://ek9.io/errors/E06120.html","title":"A generic used with a function type may only ask whether a value is set ('?')","code":"#!ek9\ndefines module error.e06120.good\n\n  defines function\n\n    validator() as abstract\n      -> text as String\n      <- rtn as Boolean?\n\n    //Uses only '?' on T, so a function type can parameterise it\n    firstSet() of type T\n      ->\n        first as T\n        second as T\n      <- rtn as T: first? <- first else second\n\n    useWithAFunction()\n      -> possiblyUnset as validator\n      <- rtn as Boolean?\n      chooser <- firstSet() of validator\n      chosen <- chooser(possiblyUnset, () is validator (rtn: false))\n      rtn: chosen(\"text\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06120"}
{"id":"errors/E06130/bad.ek9","url":"https://ek9.io/errors/E06130.html","title":"E06130: constraining type constructors must exist on parameterizing type","code":"#!ek9\ndefines module error.e06130.bad\n\n  defines record\n\n    R2 as open\n      total as Integer?\n\n      R2() as pure\n        total :=? 1\n\n      R2() as pure\n        -> initial as Integer\n        total :=? Integer(initial)\n\n      R2() as pure\n        -> other as R2\n        total :=? Integer(other.total)\n\n      operator + as pure\n        -> other as R2\n        <- rtn as R2: R2(total + other.total)\n\n      default operator ?\n\n    R3 is R2\n\n      R3() as pure\n        total :=? 1\n\n      R3() as pure\n        -> initial as Integer\n        super(initial)\n\n      default operator ?\n\n  defines function\n\n    //T(...) below needs every T to have the constructor R2 has: T(-> other as R2)\n    addAndWrap() of type T constrain by R2\n      ->\n        first as T\n        second as T\n      <- rtn as T: T(first + second)\n\n    useR3()\n      //R3 has no R3(-> other as R2) constructor\n      adder <- addAndWrap() of R3\n      require adder?","expectedOutput":null,"kind":"bad","errors":["E06130"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06130/good.ek9","url":"https://ek9.io/errors/E06130.html","title":"Give the parameterising type every constructor the constraining type has","code":"#!ek9\ndefines module error.e06130.good\n\n  defines record\n\n    R2 as open\n      total as Integer?\n\n      R2() as pure\n        total :=? 1\n\n      R2() as pure\n        -> initial as Integer\n        total :=? Integer(initial)\n\n      R2() as pure\n        -> other as R2\n        total :=? Integer(other.total)\n\n      operator + as pure\n        -> other as R2\n        <- rtn as R2: R2(total + other.total)\n\n      default operator ?\n\n    R4 is R2\n\n      R4() as pure\n        total :=? 1\n\n      R4() as pure\n        -> initial as Integer\n        super(initial)\n\n      R4() as pure\n        -> other as R2\n        super(other)\n\n      default operator ?\n\n  defines function\n\n    //T(...) below needs every T to have the constructor R2 has: T(-> other as R2)\n    addAndWrap() of type T constrain by R2\n      ->\n        first as T\n        second as T\n      <- rtn as T: T(first + second)\n\n    useR4()\n      adder <- addAndWrap() of R4\n      require adder?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06130"}
{"id":"errors/E06131/bad.ek9","url":"https://ek9.io/errors/E06131.html","title":"E06131: a constrained type must copy its base value, so the base needs either a public copy constructor or a public no-argument constructor and the ':=:' operator ('default operator')","code":"#!ek9\ndefines module error.e06131.bad\n\n  defines class\n    Base as open\n      a as String: String()\n\n      Base() as pure\n        a :=? \"x\"\n\n      default operator\n\n    //Only INHERITS ':=:(Base)' - cannot copy 'extra'.\n    Derived is Base\n      extra as String: String()\n\n      Derived() as pure\n        super()\n        extra :=? \"y\"\n\n      extraValue() as pure\n        <- rtn as String: extra\n\n      default operator ?\n\n    //Declares its own ':=:' but it takes the SUPER type, not SuperTyped.\n    SuperTyped is Base\n      extra as String: String()\n\n      SuperTyped() as pure\n        super()\n        extra :=? \"y\"\n\n      extraValue() as pure\n        <- rtn as String: extra\n\n      override operator :=:\n        -> other as Base\n        extra :=: $other\n\n      default operator ?\n\n    //Declares a ':=:' taking an unrelated type.\n    Holder\n      text as String: String()\n\n      Holder() as pure\n        text :=? \"x\"\n\n      textValue() as pure\n        <- rtn as String: text\n\n      operator :=:\n        -> other as String\n        text :=: other\n\n      default operator ?\n\n  defines type\n\n    WrappedDerived as Derived\n\n    WrappedSuperTyped as SuperTyped\n\n    WrappedHolder as Holder","expectedOutput":null,"kind":"bad","errors":["E06131"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06131/good.ek9","url":"https://ek9.io/errors/E06131.html","title":"Give the base a copy it can use: a public copy constructor, or ':=:' taking exactly the type","code":"#!ek9\ndefines module error.e06131.good\n\n  defines class\n\n    Base as open\n      a as String: String()\n      Base() as pure\n        a :=? \"x\"\n      default operator\n\n    //Its own default ':=:' takes Derived and copies 'extra' too\n    Derived is Base\n      extra as String: String()\n      Derived() as pure\n        super()\n        extra :=? \"y\"\n      extraValue() as pure\n        <- rtn as String: extra\n      default operator\n\n  defines type\n    WrappedDerived as Derived","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06131"}
{"id":"errors/E06132/bad.ek9","url":"https://ek9.io/errors/E06132.html","title":"E06132: a collection cannot carry a type invariant: its only usable constraints are whole-container predicates ('contains'), which are 'require' preconditions, and a mutating operator would re-validate on every '+=' - so a mutation could break it; constrain the ELEMENT type instead ('List of MyConstrainedElement'), which holds for every element however the collection is assembled","code":"#!ek9\ndefines module error.e06132.bad\n\n  defines type\n\n    //The RIGHT tool: constrain the ELEMENT, then hold a collection of it. The guarantee holds for\n    //every element however the list is assembled.\n    Tag as String constrain as\n      matches /^[a-z]+$/\n\n    //The wrong tool: a constrained collection. 'List of String' can never be unset, so the\n    //constrained type has no unset state to borrow.\n    Tags as List of String constrain as\n      contains \"req\"\n\n    //Same for any other parameterised generic.\n    Lookup as Dict of (String, Integer) constrain as\n      contains \"req\"","expectedOutput":null,"kind":"bad","errors":["E06132"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06132/good.ek9","url":"https://ek9.io/errors/E06132.html","title":"Constrain the ELEMENT type, then hold a collection of it","code":"#!ek9\ndefines module error.e06132.good\n\n  defines type\n\n    Tag as String constrain as\n      matches /^[a-z]+$/\n\n  defines function\n\n    tags()\n      <- rtn as List of Tag: [Tag(\"req\"), Tag(\"opt\")]","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06132"}
{"id":"errors/E06140/bad.ek9","url":"https://ek9.io/errors/E06140.html","title":"E06140: ambiguous match","code":"#!ek9\ndefines module error.e06140.bad\n\n  defines trait\n\n    Valued\n      amount() as abstract\n        <- rtn as Integer?\n\n  defines class\n\n    A as open\n      default A() as pure\n\n    B extends A as open\n      default B() as pure\n\n    C extends B with trait of Valued\n      default C() as pure\n\n      override amount()\n        <- rtn <- 42\n\n    Checker\n      check()\n        -> candidate as A\n        <- rtn as Boolean: candidate?\n\n      check()\n        -> candidate as Valued\n        <- rtn as Boolean: candidate?\n\n  defines program\n\n    Ambiguous()\n      stdout <- Stdout()\n      checker <- Checker()\n      //C reaches A through B (0.05 + 0.05) and Valued directly (0.10): equal cost\n      stdout.println($checker.check(C()))","expectedOutput":null,"kind":"bad","errors":["E06140"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06140/good.ek9","url":"https://ek9.io/errors/E06140.html","title":"Make one candidate a closer match - here B, one step from C - so the costs differ","code":"#!ek9\ndefines module error.e06140.good\n\n  defines trait\n\n    Valued\n      amount() as abstract\n        <- rtn as Integer?\n\n  defines class\n\n    A as open\n      default A() as pure\n\n    B extends A as open\n      default B() as pure\n\n    C extends B with trait of Valued\n      default C() as pure\n\n      override amount()\n        <- rtn <- 42\n\n    Checker\n      check()\n        -> candidate as B\n        <- rtn as Boolean: candidate?\n\n      check()\n        -> candidate as Valued\n        <- rtn as Boolean: candidate?\n\n  defines program\n\n    Unambiguous()\n      stdout <- Stdout()\n      checker <- Checker()\n      stdout.println($checker.check(C()))","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06140"}
{"id":"errors/E06150/bad.ek9","url":"https://ek9.io/errors/E06150.html","title":"E06150: conflicting methods to be resolved","code":"#!ek9\ndefines module error.e06150.bad\n\n  defines trait\n\n    T1\n      clash()\n        <- rtn <- true\n\n    T2\n      clash()\n        <- rtn <- false\n\n  defines class\n\n    Base as open\n      clash()\n        <- rtn <- false\n\n      default operator ?\n\n    //Two traits both provide a concrete clash()\n    BrokenClass1 with trait T1, T2\n      default BrokenClass1()\n\n      someMethod()\n        <- rtn <- true\n      default operator ?\n\n    //The base class and a trait both provide a concrete clash()\n    BrokenClass2 extends Base with trait T1\n      default BrokenClass2()\n\n      someMethod()\n        <- rtn <- true\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E06150"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06150/good.ek9","url":"https://ek9.io/errors/E06150.html","title":"Override the method and say which implementation (or what combination) you mean","code":"#!ek9\ndefines module error.e06150.good\n\n  defines trait\n\n    T1\n      clash()\n        <- rtn <- true\n\n    T2\n      clash()\n        <- rtn <- false\n\n  defines class\n\n    Base as open\n      clash()\n        <- rtn <- false\n\n      default operator ?\n\n    WorkingClass1 with trait T1, T2\n      default WorkingClass1()\n\n      override clash()\n        <- rtn as Boolean: T1.clash() and T2.clash()\n\n      default operator ?\n\n    WorkingClass2 is Base with trait T1\n      default WorkingClass2()\n\n      override clash()\n        <- rtn as Boolean: super.clash() or T1.clash()\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06150"}
{"id":"errors/E06160/bad.ek9","url":"https://ek9.io/errors/E06160.html","title":"E06160: not an immediate trait of this context","code":"#!ek9\ndefines module error.e06160.bad\n\n  defines trait\n\n    T2\n      simpleMessage() as pure\n        <- rtn as String: \"T2\"\n\n    T1 extends T2\n      anotherMessage() as pure\n        <- rtn as String: \"T1\"\n\n  defines class\n\n    //Declares T1, which extends T2: only T1 is an immediate trait\n    ViaSuperTrait with trait of T1\n\n      describe()\n        <- rtn as String?\n        first <- T2.simpleMessage()\n        second <- T1.anotherMessage()\n        rtn: first + second\n\n    //Declares no trait at all\n    NoTrait\n\n      describe()\n        <- rtn as String?\n        rtn: T2.simpleMessage()","expectedOutput":null,"kind":"bad","errors":["E06160"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06160/good.ek9","url":"https://ek9.io/errors/E06160.html","title":"Qualify a call only with a trait the class names itself; an inherited method is just called","code":"#!ek9\ndefines module error.e06160.good\n\n  defines trait\n\n    T2\n      simpleMessage() as pure\n        <- rtn as String: \"T2\"\n\n    T1 extends T2\n      anotherMessage() as pure\n        <- rtn as String: \"T1\"\n\n  defines class\n\n    ViaSuperTrait with trait of T1\n\n      describe()\n        <- rtn as String?\n        first <- simpleMessage()\n        second <- T1.anotherMessage()\n        rtn: first + second\n\n    DirectTrait with trait of T2\n\n      describe()\n        <- rtn as String: T2.simpleMessage()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06160"}
{"id":"errors/E06170/bad.ek9","url":"https://ek9.io/errors/E06170.html","title":"E06170: trait method access not supported here","code":"#!ek9\ndefines module error.e06170.bad\n\n  defines trait\n\n    T2\n      simpleMessage() as pure\n        <- rtn as String: \"T2\"\n\n  defines function\n\n    //Trait method call from standalone function - not allowed\n    SomeFunction()\n      var <- T2.simpleMessage()\n      require var?\n\n    //Dynamic function trying to access trait - not allowed\n    TestDynamicFunction()\n      var <- String()\n\n      someFunction <- () is Acceptor of String as function ( t :=: T2.simpleMessage() )\n      someFunction(var)\n\n  defines class\n\n    //Even in a class with the trait, dynamic functions can't access it\n    InvalidT2AccessFromDynamicFunctionInClass with trait of T2\n\n      NotAllowedFromDynamicClass()\n        var <- String()\n        someFunction <- () is Acceptor of String as function ( t :=: T2.simpleMessage() )\n        someFunction(var)","expectedOutput":null,"kind":"bad","errors":["E06170"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06170/good.ek9","url":"https://ek9.io/errors/E06170.html","title":"Call trait methods only where the trait is an immediate trait: a class, or a dynamic class that names it","code":"#!ek9\ndefines module error.e06170.good\n\n  defines constant\n    MaximumLength <- 300\n\n  defines trait\n\n    T2\n      simpleMessage() as pure\n        <- rtn as String: \"T2\"\n\n    LengthValidator\n      validateLength() as abstract\n        -> text as String\n        <- valid as Boolean?\n\n  defines function\n\n    validDynamicClass()\n      <- rtn as Boolean?\n      validator <- () with trait of LengthValidator, T2 as class\n        override validateLength()\n          -> text as String\n          <- valid as Boolean: false\n          if text?\n            message <- `${T2.simpleMessage()}: ${text}`\n            valid: length message < MaximumLength\n\n      rtn: validator.validateLength(\"Steve\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06170"}
{"id":"errors/E06180/bad.ek9","url":"https://ek9.io/errors/E06180.html","title":"E06180: not accessible from this context","code":"#!ek9\ndefines module error.e06180.bad\n\n  defines class\n\n    Account as open\n      balance as Integer: 0\n\n      default private Account()\n\n      Account()\n        -> opening as Integer\n        balance: opening\n\n      private audit()\n        <- rtn as Boolean: balance >= 0\n\n      protected adjust()\n        -> amount as Integer\n        balance += amount\n\n      default operator ?\n\n    Savings extends Account\n\n      Savings()\n        //The no-argument constructor is private to Account\n        super()\n\n      check()\n        <- rtn as Boolean?\n        //A private method is not visible to a sub-type\n        rtn: audit()\n\n      default operator ?\n\n    Auditor\n\n      correct()\n        -> account as Savings\n        //A protected method is visible only within the hierarchy\n        account.adjust(1)\n\n    Splitter\n      pivot as Integer: 10\n\n      above()\n        //A dynamic function's body is not inside Splitter: it cannot name pivot\n        <- rtn as Predicate of Integer: () is Predicate of Integer as pure function\n          r: t > pivot\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E06180"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06180/good.ek9","url":"https://ek9.io/errors/E06180.html","title":"Call what the context can see: a public constructor, a protected method from the sub-type, and capture the property","code":"#!ek9\ndefines module error.e06180.good\n\n  defines class\n\n    Account as open\n      balance as Integer: 0\n\n      default private Account()\n\n      Account()\n        -> opening as Integer\n        balance: opening\n\n      protected audit()\n        <- rtn as Boolean: balance >= 0\n\n      adjust()\n        -> amount as Integer\n        balance += amount\n\n      default operator ?\n\n    Savings extends Account\n\n      Savings()\n        super(0)\n\n      check()\n        <- rtn as Boolean: audit()\n\n      default operator ?\n\n    Auditor\n\n      correct()\n        -> account as Savings\n        account.adjust(1)\n\n    Splitter\n      pivot as Integer: 10\n\n      //The capture list is evaluated in above(), where pivot is visible\n      above()\n        <- rtn as Predicate of Integer: (limit: pivot) is Predicate of Integer as pure function\n          r: t > limit\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06180"}
{"id":"errors/E06190/bad.ek9","url":"https://ek9.io/errors/E06190.html","title":"E06190: EK9 Result must be used with two different types","code":"#!ek9\ndefines module error.e06190.bad\n\n  defines function\n\n    notAllowedWithSameType() as abstract\n      <- rtn as Result of (String, String)?","expectedOutput":null,"kind":"bad","errors":["E06190"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06190/good.ek9","url":"https://ek9.io/errors/E06190.html","title":"Give Result two different types: the success type and the error type","code":"#!ek9\ndefines module error.e06190.good\n\n  defines record\n\n    Failure\n      reason as String: String()\n      default operator ?\n\n  defines function\n\n    parsed() as abstract\n      <- rtn as Result of (String, Failure)?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06190"}
{"id":"errors/E06200/bad.ek9","url":"https://ek9.io/errors/E06200.html","title":"E06200: use of parenthesis '( )' not allowed in this context","code":"#!ek9\ndefines module error.e06200.bad\n\n  defines function\n\n    misplacedParentheses()\n      //In a TYPE, no parentheses: the type is 'List of String'\n      names as List() of String?\n\n      //Only the outermost construction takes them: the inner type is a type\n      nested <- List() of List() of String","expectedOutput":null,"kind":"bad","errors":["E06200"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06200/good.ek9","url":"https://ek9.io/errors/E06200.html","title":"Parentheses construct, 'of' parameterises: List() of String, and a type is List of String","code":"#!ek9\ndefines module error.e06200.good\n\n  defines function\n\n    wellPlacedParentheses()\n      <- rtn as Integer?\n      names as List of String: List()\n      nested <- List() of List of String\n      rtn: length names + length nested","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06200"}
{"id":"errors/E06210/bad.ek9","url":"https://ek9.io/errors/E06210.html","title":"E06210: parenthesis '( )' required in this context","code":"#!ek9\ndefines module error.e06210.bad\n\n  defines function\n\n    echo() of type T as pure\n      -> item as T\n      <- rtn as T: item\n\n    <?-\n      Valid: the parentheses before the type arguments.\n    -?>\n    ValidForm()\n      names <- List() of String\n      counts <- Dict() of (String, Integer)\n      require names? and counts?\n\n    OneTypeArgument()\n      names <- List of String()\n\n    TwoTypeArguments()\n      counts <- Dict of (String, Integer)()\n\n    NestedTypeArgument()\n      nested <- List of List of String()\n\n    GenericFunction()\n      echoed <- echo of Integer()","expectedOutput":null,"kind":"bad","errors":["E06210"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06210/good.ek9","url":"https://ek9.io/errors/E06210.html","title":"Put the parentheses before the type arguments: List() of String","code":"#!ek9\ndefines module error.e06210.good\n\n  defines function\n\n    echo() of type T as pure\n      -> item as T\n      <- rtn as T: item\n\n    validForm()\n      <- rtn as Integer?\n      names <- List() of String\n      counts <- Dict() of (String, Integer)\n      nested <- List() of List of String\n      echoed <- echo() of Integer\n      rtn: length names + length counts + length nested + echoed(1)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06210"}
{"id":"errors/E06220/bad.ek9","url":"https://ek9.io/errors/E06220.html","title":"E06220: choose either empty parenthesis '( )' with values or a type definition","code":"#!ek9\ndefines module error.e06220.bad\n\n  defines class\n\n    Holder of type T\n      item as T: T()\n\n      default Holder()\n\n      Holder()\n        -> initial as T\n        item: initial\n\n      default operator ?\n\n  defines function\n\n    mixed()\n      //An argument already says what T is; 'of Integer' says it again\n      holder <- Holder(32) of Integer","expectedOutput":null,"kind":"bad","errors":["E06220"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06220/good.ek9","url":"https://ek9.io/errors/E06220.html","title":"Let the argument give the type: Holder(32) is a Holder of Integer","code":"#!ek9\ndefines module error.e06220.good\n\n  defines class\n\n    Holder of type T\n      item as T: T()\n\n      default Holder()\n\n      Holder()\n        -> initial as T\n        item: initial\n\n      default operator ?\n\n  defines function\n\n    inferred()\n      <- rtn as Boolean?\n      holder <- Holder(32)\n      rtn: holder?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06220"}
{"id":"errors/E06220/good_explicit.ek9","url":"https://ek9.io/errors/E06220.html","title":"Or construct with no argument and name the type","code":"#!ek9\ndefines module error.e06220.good.explicit\n\n  defines class\n\n    Holder of type T\n      item as T: T()\n\n      default Holder()\n\n      Holder()\n        -> initial as T\n        item: initial\n\n      default operator ?\n\n  defines function\n\n    explicit()\n      <- rtn as Boolean?\n      holder <- Holder() of Integer\n      rtn: holder?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06220"}
{"id":"errors/E06230/bad.ek9","url":"https://ek9.io/errors/E06230.html","title":"E06230: variables being captured must be named when not just using identifiers","code":"#!ek9\ndefines module error.e06230.bad\n\n  defines function\n\n    threshold() as pure\n      <- rtn as Integer: 42\n\n    discriminator() as abstract\n      -> text as String\n      <- rtn as Boolean?\n\n  defines program\n\n    UnnamedCaptures()\n      //A capture that is not just a variable needs a name the body can use\n      longer <- (threshold()) is discriminator as function\n        rtn: length text > threshold\n\n      shorter <- (100) is discriminator as function\n        rtn: length text < max","expectedOutput":null,"kind":"bad","errors":["E06230"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06230/good.ek9","url":"https://ek9.io/errors/E06230.html","title":"Name each captured expression: (min: threshold()), (max: 100)","code":"#!ek9\ndefines module error.e06230.good\n\n  defines function\n\n    threshold() as pure\n      <- rtn as Integer: 42\n\n    discriminator() as abstract\n      -> text as String\n      <- rtn as Boolean?\n\n  defines program\n\n    NamedCaptures()\n      stdout <- Stdout()\n\n      longer <- (min: threshold()) is discriminator as function\n        rtn: length text > min\n\n      shorter <- (max: 100) is discriminator as function\n        rtn: length text < max\n\n      stdout.println(`${longer(\"a sentence\")} ${shorter(\"a sentence\")}`)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06230"}
{"id":"errors/E06240/bad.ek9","url":"https://ek9.io/errors/E06240.html","title":"E06240: either all variable must be named or none, when passing parameters","code":"#!ek9\ndefines module error.e06240.bad\n\n  defines trait\n\n    RangeCheck\n      within()\n        -> text as String\n        <- result as Boolean?\n\n  defines program\n\n    MixedCaptures()\n      max <- 100\n\n      //One capture named, one not\n      check <- (min: 10, max) with trait of RangeCheck as class\n        override within()\n          -> text as String\n          <- result as Boolean: length text > min and length text < max","expectedOutput":null,"kind":"bad","errors":["E06240"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06240/good.ek9","url":"https://ek9.io/errors/E06240.html","title":"Name every capture, or none","code":"#!ek9\ndefines module error.e06240.good\n\n  defines trait\n\n    RangeCheck\n      within()\n        -> text as String\n        <- result as Boolean?\n\n  defines program\n\n    AllNamed()\n      stdout <- Stdout()\n      max <- 100\n\n      check <- (min: 10, max: max) with trait of RangeCheck as class\n        override within()\n          -> text as String\n          <- result as Boolean: length text > min and length text < max\n        default operator ?\n\n      stdout.println($check.within(\"short\"))","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06240"}
{"id":"errors/E06240/good_positional.ek9","url":"https://ek9.io/errors/E06240.html","title":"Or capture plain variables only, all unnamed","code":"#!ek9\ndefines module error.e06240.good.positional\n\n  defines trait\n\n    RangeCheck\n      within()\n        -> text as String\n        <- result as Boolean?\n\n  defines program\n\n    AllPositional()\n      stdout <- Stdout()\n      min <- 10\n      max <- 100\n\n      check <- (min, max) with trait of RangeCheck as class\n        override within()\n          -> text as String\n          <- result as Boolean: length text > min and length text < max\n        default operator ?\n\n      stdout.println($check.within(\"short\"))","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06240"}
{"id":"errors/E06250/bad.ek9","url":"https://ek9.io/errors/E06250.html","title":"E06250: the order and naming of arguments must match parameters","code":"#!ek9\ndefines module error.e06250.bad\n\n  defines class\n\n    Ledger\n      record()\n        ->\n          label as String\n          amount as Float\n        <- rtn as Boolean: label? and amount?\n\n  defines function\n\n    wrongNames()\n      <- rtn as Boolean?\n      ledger <- Ledger()\n      rtn: ledger.record(\n        name: \"Steve\",\n        total: 1.0\n        )\n\n    wrongOrder()\n      <- rtn as Boolean?\n      ledger <- Ledger()\n      rtn: ledger.record(\n        amount: \"Steve\",\n        label: 1.0\n        )","expectedOutput":null,"kind":"bad","errors":["E06250"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06250/good.ek9","url":"https://ek9.io/errors/E06250.html","title":"Use the parameters' own names, in their own order","code":"#!ek9\ndefines module error.e06250.good\n\n  defines class\n\n    Ledger\n      record()\n        ->\n          label as String\n          amount as Float\n        <- rtn as Boolean: label? and amount?\n\n  defines function\n\n    rightNames()\n      <- rtn as Boolean?\n      ledger <- Ledger()\n      rtn: ledger.record(label: \"Steve\", amount: 1.0)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06250"}
{"id":"errors/E06260/bad.ek9","url":"https://ek9.io/errors/E06260.html","title":"E06260: parameter mismatch","code":"#!ek9\ndefines module error.e06260.bad\n\n  defines package\n\n    version <- \"1.0.0-0\"\n\n    description <- 12\n\n    license <- 1.0.0-0\n\n    publicAccess <- \"yes\"\n\n    applyStandardIncludes <- \"true\"\n\n    applyStandardExcludes <- 0\n\n    tags <- \"tools\"\n\n    deps <- {\"a.b\": 1.0.0-0}\n\n    name <- \"myLib\"","expectedOutput":null,"kind":"bad","errors":["E06260"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06260/good.ek9","url":"https://ek9.io/errors/E06260.html","title":"Give each package property a value of its own kind","code":"#!ek9\ndefines module error.e06260.good\n\n  defines package\n    version <- 1.0.0-0\n    description <- \"A library\"\n    license <- \"MIT\"\n    publicAccess <- true\n    applyStandardIncludes <- true\n    applyStandardExcludes <- false\n    tags <- [\"tools\"]","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06260"}
{"id":"errors/E06270/bad.ek9","url":"https://ek9.io/errors/E06270.html","title":"E06270: parameter mismatch","code":"#!ek9\ndefines module error.e06270.bad\n\n  defines function\n\n    counter() as abstract\n      <- rtn as Integer?\n\n  defines class\n\n    Tally\n      source as counter?\n\n      default private Tally()\n\n      Tally()\n        -> callback as counter\n        this.source: callback\n\n      current()\n        <- rtn as Integer?\n        //The delegate takes no arguments\n        rtn: source(21)\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E06270"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06270/good.ek9","url":"https://ek9.io/errors/E06270.html","title":"Call the delegate with the arguments its function type declares - here none","code":"#!ek9\ndefines module error.e06270.good\n\n  defines function\n\n    counter() as abstract\n      <- rtn as Integer?\n\n  defines class\n\n    Tally\n      source as counter?\n\n      default private Tally()\n\n      Tally()\n        -> callback as counter\n        this.source: callback\n\n      current()\n        <- rtn as Integer: source()\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06270"}
{"id":"errors/E06280/bad.ek9","url":"https://ek9.io/errors/E06280.html","title":"E06280: too many arguments","code":"#!ek9\ndefines module error.e06280.bad\n\n  defines class\n\n    Amount\n      total as Integer: 0\n\n      //'+' takes the right-hand operand only: the left is this\n      operator + as pure\n        ->\n          first as Amount\n          second as Amount\n        <- rtn as Amount: Amount()\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E06280"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06280/good.ek9","url":"https://ek9.io/errors/E06280.html","title":"A binary operator takes one parameter: the right-hand operand","code":"#!ek9\ndefines module error.e06280.good\n\n  defines class\n\n    Amount\n      total as Integer?\n\n      default private Amount() as pure\n\n      Amount() as pure\n        -> initial as Integer\n        total :=? initial\n\n      operator + as pure\n        -> other as Amount\n        <- rtn as Amount: Amount(total + other.total)\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06280"}
{"id":"errors/E06290/bad.ek9","url":"https://ek9.io/errors/E06290.html","title":"E06290: too few arguments","code":"#!ek9\ndefines module error.e06290.bad\n\n  defines class\n\n    Amount\n      total as Integer: 0\n\n      default Amount() as pure\n\n      //'+' needs the right-hand operand\n      operator + as pure\n        <- rtn as Amount: Amount()\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E06290"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06290/good.ek9","url":"https://ek9.io/errors/E06290.html","title":"Give the binary operator its one parameter","code":"#!ek9\ndefines module error.e06290.good\n\n  defines class\n\n    Amount\n      total as Integer?\n\n      default private Amount() as pure\n\n      Amount() as pure\n        -> initial as Integer\n        total :=? initial\n\n      operator + as pure\n        -> other as Amount\n        <- rtn as Amount: Amount(total + other.total)\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06290"}
{"id":"errors/E06300/bad.ek9","url":"https://ek9.io/errors/E06300.html","title":"E06300: require one argument only","code":"#!ek9\ndefines module error.e06300.bad\n\n  defines function\n\n    joined()\n      ->\n        first as Integer\n        second as Integer\n      <- rtn as String: `${first}${second}`\n\n    mapTwoAtATime()\n      stdout <- Stdout()\n      //'map' passes ONE item at a time\n      cat [1, 2, 3] | map with joined > stdout","expectedOutput":null,"kind":"bad","errors":["E06300"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06300/good.ek9","url":"https://ek9.io/errors/E06300.html","title":"Give 'map' a function of one parameter","code":"#!ek9\ndefines module error.e06300.good\n\n  defines function\n\n    asText()\n      -> number as Integer\n      <- rtn as String: `#${number}`\n\n    mapOneAtATime()\n      stdout <- Stdout()\n      cat [1, 2, 3] | map with asText > stdout","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06300"}
{"id":"errors/E06310/bad.ek9","url":"https://ek9.io/errors/E06310.html","title":"E06310: function must have no arguments","code":"#!ek9\ndefines module error.e06310.bad\n\n  defines function\n\n    doubled()\n      -> number as Integer\n      <- rtn as Integer: number * 2\n\n    callNeedsArguments()\n      <- rtn as List of Integer?\n      //'call' calls each function with NO arguments\n      rtn: cat [doubled] | call | collect as List of Integer","expectedOutput":null,"kind":"bad","errors":["E06310"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06310/good.ek9","url":"https://ek9.io/errors/E06310.html","title":"Give 'call' functions that take no arguments - or 'map with' a function of one","code":"#!ek9\ndefines module error.e06310.good\n\n  defines function\n\n    answer()\n      <- rtn as Integer: 42\n\n    doubled()\n      -> number as Integer\n      <- rtn as Integer: number * 2\n\n    callAndMap()\n      <- rtn as List of Integer: cat [answer] | call | map with doubled | collect as List of Integer","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06310"}
{"id":"errors/E06320/bad.ek9","url":"https://ek9.io/errors/E06320.html","title":"E06320: invalid number of parameters","code":"#!ek9\ndefines module error.e06320.bad\n\n  defines class\n\n    Processor\n\n      //A dispatcher routes on its parameter: it needs one or two\n      process() as dispatcher\n        <- rtn as String: \"nothing\"\n\n      process()\n        -> input as Integer\n        <- rtn as String: $input","expectedOutput":null,"kind":"bad","errors":["E06320"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06320/good.ek9","url":"https://ek9.io/errors/E06320.html","title":"Give the dispatcher entry point the parameter it routes on","code":"#!ek9\ndefines module error.e06320.good\n\n  defines class\n\n    Processor\n\n      process() as dispatcher\n        -> input as Any\n        <- rtn as String: \"something\"\n\n      process()\n        -> input as Integer\n        <- rtn as String: $input\n\n      process()\n        -> input as String\n        <- rtn as String: input","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06320"}
{"id":"errors/E06330/bad.ek9","url":"https://ek9.io/errors/E06330.html","title":"E06330: argument types are not compatible with each other","code":"#!ek9\ndefines module error.e06330.bad\n\n  defines function\n\n    InvalidProp1ComparatorC()\n      ->\n        o1 as Date\n        o2 as R1\n      <-\n        rtn as Integer: 66\n\n    InvalidProp1ComparatorE()\n      ->\n        o1 as Duration\n        o2 as Duration\n      <-\n        rtn as Integer: 1\n\n  defines record\n    R1\n      prop1 as String: String()\n      prop2 as Date: Date()\n\n      R1()\n        ->\n          p1 as String\n          p2 as Date\n        this.prop1 :=: p1\n        this.prop2 :=: p2\n\n      default operator\n\n  defines function\n\n    InvalidComparatorFunctionStreamCatSort3()\n      stdout <- Stdout()\n\n      cat [R1(\"last\", 2010-10-01), R1(\"last\", 2010-10-02), R1(\"first\", 2010-10-01)] | sort with InvalidProp1ComparatorC > stdout\n\n    InvalidComparatorFunctionStreamCatSort5()\n      stdout <- Stdout()\n\n      cat [R1(\"last\", 2010-10-01), R1(\"last\", 2010-10-02), R1(\"first\", 2010-10-01)] | sort with InvalidProp1ComparatorE > stdout","expectedOutput":null,"kind":"bad","errors":["E06330"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E06330/good.ek9","url":"https://ek9.io/errors/E06330.html","title":"The comparator takes two of the item type and returns an Integer","code":"#!ek9\ndefines module error.e06330.good\n\n  defines record\n\n    R1\n      prop1 as String: String()\n      prop2 as Date: Date()\n\n      R1()\n        ->\n          p1 as String\n          p2 as Date\n        this.prop1 :=: p1\n        this.prop2 :=: p2\n\n      default operator\n\n  defines function\n    Prop1R1Comparator()\n      ->\n        o1 as R1\n        o2 as R1\n      <-\n        rtn as Integer: o1.prop1 <=> o2.prop1\n\n    ComparatorFunctionStreamCatSort4()\n      stdout <- Stdout()\n\n      cat [R1(\"last\", 2010-10-01), R1(\"last\", 2010-10-02), R1(\"first\", 2010-10-01)] | sort with Prop1R1Comparator > stdout","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E06330"}
{"id":"errors/E07010/bad.ek9","url":"https://ek9.io/errors/E07010.html","title":"E07010: remove 'override' with use of 'private' access modifier","code":"#!ek9\ndefines module error.e07010.bad\n\n  defines class\n\n    Account as open\n      private auditCode()\n        <- rtn as String: \"A\"\n\n    Savings extends Account\n\n      //A private method cannot override, and a private parent method cannot be overridden\n      override private auditCode()\n        <- rtn as String: \"S\"","expectedOutput":null,"kind":"bad","errors":["E07010"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07010/good.ek9","url":"https://ek9.io/errors/E07010.html","title":"Override a visible method, and drop private","code":"#!ek9\ndefines module error.e07010.good\n\n  defines class\n\n    Account as open\n      auditCode()\n        <- rtn as String: \"A\"\n\n    Savings extends Account\n      override auditCode()\n        <- rtn as String: \"S\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07010"}
{"id":"errors/E07020/bad.ek9","url":"https://ek9.io/errors/E07020.html","title":"E07020: 'override' of a method/operator and 'abstract' (no implementation) is not logical","code":"#!ek9\ndefines module error.e07020.bad\n\n  defines class\n\n    Shape as abstract\n      area() as abstract\n        <- rtn as Float?\n\n    Polygon extends Shape as abstract\n\n      //override says \"this implements it\", abstract says \"there is no implementation\"\n      override area() as abstract\n        <- rtn as Float?","expectedOutput":null,"kind":"bad","errors":["E07020"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07020/good.ek9","url":"https://ek9.io/errors/E07020.html","title":"Either implement it with override, or leave it abstract and do not redeclare it","code":"#!ek9\ndefines module error.e07020.good\n\n  defines class\n\n    Shape as abstract\n      area() as abstract\n        <- rtn as Float?\n\n    //Still abstract: it simply inherits area() and does not redeclare it\n    Polygon extends Shape as abstract\n      sides() as abstract\n        <- rtn as Integer?\n\n    //Concrete: it overrides area() with a body\n    Square extends Polygon\n      override area()\n        <- rtn as Float: 4.0\n\n      override sides()\n        <- rtn as Integer: 4","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07020"}
{"id":"errors/E07030/bad.ek9","url":"https://ek9.io/errors/E07030.html","title":"E07030: 'default' of operators on a trait is not supported","code":"#!ek9\ndefines module error.e07030.bad\n\n  defines trait\n\n    Describable\n      describe() as pure abstract\n        <- rtn as String?\n\n      //A trait has no fields to generate an operator from\n      default operator $","expectedOutput":null,"kind":"bad","errors":["E07030"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07030/good.ek9","url":"https://ek9.io/errors/E07030.html","title":"Write the trait's operator, over the trait's own methods","code":"#!ek9\ndefines module error.e07030.good\n\n  defines trait\n\n    Describable\n      describe() as pure abstract\n        <- rtn as String?\n\n      //Give the trait's operator a body, written over the trait's own methods\n      operator $ as pure\n        <- rtn as String: describe()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07030"}
{"id":"errors/E07040/bad.ek9","url":"https://ek9.io/errors/E07040.html","title":"E07040: 'by' variable is not supported on a trait only on a class","code":"#!ek9\ndefines module error.e07040.bad\n\n  defines trait\n    Reader\n      read()\n        <- rtn as String: \"read\"\n\n    Writer\n      write()\n        -> text as String\n        <- rtn as Boolean: text?\n\n    //A trait has no properties, so it has nothing to delegate 'by'\n    ReaderWriter with trait of Reader by reader, Writer","expectedOutput":null,"kind":"bad","errors":["E07040"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07040/good.ek9","url":"https://ek9.io/errors/E07040.html","title":"Delegate 'by' a property in a class","code":"#!ek9\ndefines module error.e07040.good\n\n  defines trait\n    Reader\n      read() as abstract\n        <- rtn as String?\n\n  defines class\n    FileReader with trait of Reader\n      override read()\n        <- rtn as String: \"read from file\"\n\n    //A class can delegate a trait 'by' one of its properties\n    Document with trait of Reader by reader\n      reader as Reader: FileReader()\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07040"}
{"id":"errors/E07050/bad.ek9","url":"https://ek9.io/errors/E07050.html","title":"E07050: 'abstract' modifier on a constructor is not logical","code":"#!ek9\ndefines module error.e07050.bad\n\n  defines class\n\n    Counter as abstract\n\n      //A constructor makes an object, so it cannot be abstract\n      Counter() as abstract\n        -> start as Integer","expectedOutput":null,"kind":"bad","errors":["E07050"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07050/good.ek9","url":"https://ek9.io/errors/E07050.html","title":"Give the constructor a body","code":"#!ek9\ndefines module error.e07050.good\n\n  defines class\n\n    Counter\n      count as Integer?\n\n      default private Counter()\n\n      Counter()\n        -> start as Integer\n        this.count: start\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07050"}
{"id":"errors/E07060/bad.ek9","url":"https://ek9.io/errors/E07060.html","title":"E07060: 'override' is not required on a constructor","code":"#!ek9\ndefines module error.e07060.bad\n\n  defines class\n\n    Base as open\n      default Base()\n\n    Derived extends Base\n\n      //Constructors are never inherited, so there is nothing to override\n      override Derived()\n        super()","expectedOutput":null,"kind":"bad","errors":["E07060"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07060/good.ek9","url":"https://ek9.io/errors/E07060.html","title":"Remove 'override' from the constructor","code":"#!ek9\ndefines module error.e07060.good\n\n  defines class\n\n    Base as open\n      default Base()\n\n    Derived extends Base\n      Derived()\n        super()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07060"}
{"id":"errors/E07070/bad.ek9","url":"https://ek9.io/errors/E07070.html","title":"E07070: traits do not support constructor methods","code":"#!ek9\ndefines module error.e07070.bad\n\n  defines trait\n    Nameable\n\n      //A trait is never constructed on its own\n      Nameable()","expectedOutput":null,"kind":"bad","errors":["E07070"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07070/good.ek9","url":"https://ek9.io/errors/E07070.html","title":"Construct the class that has the trait","code":"#!ek9\ndefines module error.e07070.good\n\n  defines trait\n    Nameable\n      name() as abstract\n        <- rtn as String?\n\n  defines class\n    Person with trait of Nameable\n      personName as String?\n\n      default private Person()\n\n      Person()\n        -> newName as String\n        this.personName: newName\n\n      override name()\n        <- rtn as String: personName\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07070"}
{"id":"errors/E07075/bad.ek9","url":"https://ek9.io/errors/E07075.html","title":"E07075: traits do not support properties/fields","code":"#!ek9\ndefines module error.e07075.bad\n\n  defines trait\n    Nameable\n\n      //A trait holds behaviour, never state\n      personName <- \"default\"","expectedOutput":null,"kind":"bad","errors":["E07075"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07075/good.ek9","url":"https://ek9.io/errors/E07075.html","title":"Declare an abstract method on the trait, and the property on the class","code":"#!ek9\ndefines module error.e07075.good\n\n  defines trait\n    Nameable\n      name() as abstract\n        <- rtn as String?\n\n  defines class\n    Person with trait of Nameable\n      personName <- \"default\"\n\n      override name()\n        <- rtn as String: personName\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07075"}
{"id":"errors/E07080/bad.ek9","url":"https://ek9.io/errors/E07080.html","title":"E07080: 'default' constructor with parameters is not supported","code":"#!ek9\ndefines module error.e07080.bad\n\n  defines class\n\n    Counter\n\n      //A 'default' constructor is the generated no-argument one\n      default Counter()\n        -> start as Integer","expectedOutput":null,"kind":"bad","errors":["E07080"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07080/good.ek9","url":"https://ek9.io/errors/E07080.html","title":"Keep 'default' for the no-argument constructor, and write the one with parameters","code":"#!ek9\ndefines module error.e07080.good\n\n  defines class\n\n    Counter\n      count <- 0\n\n      default Counter()\n\n      Counter()\n        -> start as Integer\n        this.count: start\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07080"}
{"id":"errors/E07090/bad.ek9","url":"https://ek9.io/errors/E07090.html","title":"E07090: 'default' modifier is only valid for constructors, not regular methods","code":"#!ek9\ndefines module error.e07090.bad\n\n  defines trait\n    T1\n      //Invalid: default on regular method in trait (with body)\n      default someMethod() as pure\n        -> text as String\n        <- rtn as String: String(text)\n\n      //Valid: abstract method without default\n      anotherMethod() as pure abstract\n        -> text as String\n        <- rtn as String?\n\n  defines class\n    C1\n      //Valid: default constructor\n      default C1()\n\n      //Invalid: default on regular method with body\n      default normalMethod()\n        -> text as String\n        <- rtn as String: String(text)\n\n      //Valid: regular method without default\n      validMethod()\n        -> text as String\n        <- rtn as String: String(text)\n\n  defines record\n    R1\n      prop1 <- String()\n\n      //Valid: default constructor\n      default R1()\n\n      //Invalid: default on regular method in record\n      default getValue()\n        <- rtn as String: String(prop1)\n\n  defines component\n    Comp1\n      //Valid: default constructor\n      default Comp1()\n\n      //Invalid: default on regular method in component\n      default processData()\n        -> data as String\n        <- rtn as String: String(data)","expectedOutput":null,"kind":"bad","errors":["E07090"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07090/good.ek9","url":"https://ek9.io/errors/E07090.html","title":"Remove 'default' from the method","code":"#!ek9\ndefines module error.e07090.good\n\n  defines class\n    Greeter\n      //'default' is fine on a constructor\n      default Greeter()\n\n      //A method is written, never 'default'\n      greet()\n        -> greeting as String\n        <- rtn as String: String(greeting)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07090"}
{"id":"errors/E07100/bad.ek9","url":"https://ek9.io/errors/E07100.html","title":"E07100: defined as default/abstract but an implementation has been provided","code":"#!ek9\ndefines module error.e07100.bad\n\n  defines class\n\n    Shape as abstract\n\n      //'abstract' says there is no body, yet a value is given\n      area() as abstract\n        <- rtn as Float: 0.0","expectedOutput":null,"kind":"bad","errors":["E07100"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07100/good.ek9","url":"https://ek9.io/errors/E07100.html","title":"Remove either 'abstract' or the body","code":"#!ek9\ndefines module error.e07100.good\n\n  defines class\n\n    Shape as abstract\n      //Option 1: keep it abstract, with no body\n      area() as abstract\n        <- rtn as Float?\n\n      //Option 2: drop 'abstract', and keep the body\n      name()\n        <- rtn as String: \"shape\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07100"}
{"id":"errors/E07110/bad.ek9","url":"https://ek9.io/errors/E07110.html","title":"E07110: implementation not provided so must be declared as abstract","code":"#!ek9\ndefines module error.e07110.bad\n\n  defines class\n\n    Shape as abstract\n\n      //No body, and not marked abstract\n      area()\n        <- rtn as Float?","expectedOutput":null,"kind":"bad","errors":["E07110"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07110/good.ek9","url":"https://ek9.io/errors/E07110.html","title":"Mark it abstract, or give it a body","code":"#!ek9\ndefines module error.e07110.good\n\n  defines class\n\n    Shape as abstract\n      //Option 1: mark it abstract\n      area() as abstract\n        <- rtn as Float?\n\n      //Option 2: give it a body\n      name()\n        <- rtn as String: \"shape\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07110"}
{"id":"errors/E07120/bad.ek9","url":"https://ek9.io/errors/E07120.html","title":"E07120: base level implementation must be provided for dispatcher method","code":"#!ek9\ndefines module error.e07120.bad\n\n  defines class\n\n    Shape as open\n      kind()\n        <- rtn as String: \"shape\"\n\n    Describer\n\n      //The entry point is what runs when no more specific method matches\n      describe() as dispatcher\n        -> shape as Shape\n        <- rtn as String?","expectedOutput":null,"kind":"bad","errors":["E07120"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07120/good.ek9","url":"https://ek9.io/errors/E07120.html","title":"Give the dispatcher entry point a body","code":"#!ek9\ndefines module error.e07120.good\n\n  defines class\n\n    Shape as open\n      kind()\n        <- rtn as String: \"shape\"\n\n    Circle extends Shape\n      override kind()\n        <- rtn as String: \"circle\"\n\n    Describer\n\n      //The entry point has a body: the fallback for any Shape\n      describe() as dispatcher\n        -> shape as Shape\n        <- rtn as String: \"some \" + shape.kind()\n\n      //Chosen at run time when the Shape is a Circle\n      describe()\n        -> circle as Circle\n        <- rtn as String: \"a round \" + circle.kind()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07120"}
{"id":"errors/E07130/bad.ek9","url":"https://ek9.io/errors/E07130.html","title":"E07130: not declared abstract but still has abstract methods/operators","code":"#!ek9\ndefines module error.e07130.bad\n\n  defines trait\n\n    //Create a trait with one concrete method and some abstract methods/operators\n    T1\n      concreteMethod()\n        -> count as Integer\n        <- rtn as Boolean: count?\n\n      tMethod()\n        -> amount as Float\n        <- rtn as Boolean?\n\n      operator + as pure\n        -> amount as Float\n        <- rtn as Float?\n\n  defines class\n    //This is valid as a method is abstract and so this class is also abstract\n    C1 as abstract\n      default C1()\n\n      aMethod() as abstract\n        -> count as Integer\n        <- rtn as Boolean?\n\n      //A concrete method\n      bMethod()\n        -> count as Integer\n        <- rtn <- true\n\n      //Note that in class, we have to state that this is abstract (unlike traits)\n      operator - as pure abstract\n        -> amount as Float\n        <- rtn as Float?\n\n    //This too is valid\n    C2 with trait of T1 as abstract\n      default C2()\n\n    //But this is Ok because it marked as abstract\n    C3 extends C1 as abstract\n      default C3()\n\n    //This is an error, just marking as open is not enough, this is abstract\n    //But it is picked up in the SYMBOL_DEFINITION phase and is checked elsewhere.\n    //So it is commented out here - but left in place to highlight it is not missing\n    <!-\n    C4 as open\n      default C4()\n\n      aMethod() as abstract\n        -> count as Integer\n        <- rtn as Boolean?\n    -!>\n\n    //This is an error, this is abstract because T1.tMethod is abstract\n    C5 with trait of T1\n      default C5()\n\n    //This is an error, this is abstract because T1.tMethod is abstract and marking as open makes not difference.\n    //So even though the operator is now implemented, this not enough.\n    C6 with trait of T1 as open\n      default C6()\n\n      override operator + as pure\n        -> amount as Float\n        <- rtn as Float: amount\n\n    //Another error because C1 is abstract and C7 has not implemented and so must also be marked as abstract.\n    C7 extends C1\n      default C7()\n\n    //So still an error because the operator is still unimplemented.\n    C8 extends C1\n      default C8()\n\n      //We now override and implement\n      override aMethod()\n        -> count as Integer\n        <- rtn as Boolean: true\n\n    //So still an error because the aMethod is still unimplemented.\n    C9 extends C1\n      default C9()\n\n      //We now override and implement\n      override operator - as pure\n        -> amount as Float\n        <- rtn as Float: 0.0\n\n    //Now this will be OK, as everything is implemented.\n    C10 extends C1\n      default C10()\n\n      override aMethod()\n        -> count as Integer\n        <- rtn as Boolean: true\n\n      override operator - as pure\n        -> amount as Float\n        <- rtn as Float: 0.0\n\n    //This is now OK because all abstract method are implemented.\n    C11 with trait of T1\n      default C11()\n\n      override tMethod()\n        -> amount as Float\n        <- rtn as Boolean: true\n\n      override operator + as pure\n        -> amount as Float\n        <- rtn as Float: amount","expectedOutput":null,"kind":"bad","errors":["E07130"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07130/good.ek9","url":"https://ek9.io/errors/E07130.html","title":"Mark it abstract, or implement every abstract method","code":"#!ek9\ndefines module error.e07130.good\n\n  defines trait\n    Greeter\n      greet() as abstract\n        <- rtn as String?\n\n  defines class\n\n    //Option 1: say it is abstract\n    PartGreeter with trait of Greeter as abstract\n      default PartGreeter()\n\n    //Option 2: implement every abstract method\n    EnglishGreeter with trait of Greeter\n      override greet()\n        <- rtn as String: \"hello\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07130"}
{"id":"errors/E07130/good_delegate.ek9","url":"https://ek9.io/errors/E07130.html","title":"Delegate the trait's methods to a property","code":"#!ek9\ndefines module error.e07130.good.delegate\n\n  defines trait\n    Greeter\n      greet() as abstract\n        <- rtn as String?\n\n  defines class\n\n    EnglishGreeter with trait of Greeter\n      override greet()\n        <- rtn as String: \"hello\"\n\n    //Concrete: greet() is forwarded to the greeter property\n    PoliteGreeter with trait of Greeter by greeter\n      greeter as Greeter: EnglishGreeter()\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07130"}
{"id":"errors/E07140/bad.ek9","url":"https://ek9.io/errors/E07140.html","title":"E07140: all abstract methods/operators must be implemented","code":"#!ek9\ndefines module error.e07140.bad\n\n  defines trait\n    Processor\n      process() as abstract\n        -> input as String\n        <- output as String?\n\n      validate() as abstract\n        -> input as String\n        <- valid as Boolean?\n\n  defines program\n\n    ProcessOrder()\n      stdout <- Stdout()\n\n      //validate() is not implemented\n      processor <- () with trait of Processor as class\n        override process()\n          -> input as String\n          <- output as String: \"processed: \" + input\n\n      stdout.println(processor.process(\"order\"))","expectedOutput":null,"kind":"bad","errors":["E07140"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07140/good.ek9","url":"https://ek9.io/errors/E07140.html","title":"Implement every abstract method in the dynamic class","code":"#!ek9\ndefines module error.e07140.good\n\n  defines trait\n    Processor\n      process() as abstract\n        -> input as String\n        <- output as String?\n\n      validate() as abstract\n        -> input as String\n        <- valid as Boolean?\n\n  defines program\n\n    ProcessOrder()\n      stdout <- Stdout()\n\n      processor <- () with trait of Processor as class\n        override process()\n          -> input as String\n          <- output as String: \"processed: \" + input\n\n        override validate()\n          -> input as String\n          <- valid as Boolean: input?\n\n      if processor.validate(\"order\")\n        stdout.println(processor.process(\"order\"))","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07140"}
{"id":"errors/E07150/bad.ek9","url":"https://ek9.io/errors/E07150.html","title":"E07150: text method missing for language variant","code":"#!ek9\ndefines module error.e07150.bad\n\n  defines record\n    Person\n      firstName <- String()\n      lastName <- String()\n\n      Person() as pure\n        ->\n          firstName String\n          lastName String\n        require firstName? and lastName?\n\n        this.firstName :=? String(firstName)\n        this.lastName :=? String(lastName)\n\n      default operator ?\n\n  defines text for \"en_GB\"\n\n    //This text type has a missing method, that is present in the \"de version\"\n    WelcomePageText\n\n      namedWelcome()\n        -> person as Person\n        `Welcome ${person.firstName}`\n\n  defines text for \"de\"\n\n    WelcomePageText\n      namedWelcome()\n        -> person as Person\n        `Willkommen ${person.firstName}`\n\n      //Deliberately add method here but not for en_GB\n      namedWelcome()\n        -> name as String\n        `Willkommen ${name}`","expectedOutput":null,"kind":"bad","errors":["E07150"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07150/good.ek9","url":"https://ek9.io/errors/E07150.html","title":"Every locale provides every text method","code":"#!ek9\ndefines module error.e07150.good\n\n  defines text for \"en_GB\"\n\n    WelcomePageText\n      namedWelcome()\n        -> name as String\n        `Welcome ${name}`\n\n      formalWelcome()\n        -> name as String\n        `Good day ${name}`\n\n  defines text for \"de\"\n\n    WelcomePageText\n      namedWelcome()\n        -> name as String\n        `Willkommen ${name}`\n\n      formalWelcome()\n        -> name as String\n        `Guten Tag ${name}`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07150"}
{"id":"errors/E07155/bad.ek9","url":"https://ek9.io/errors/E07155.html","title":"E07155: text type already defined for this locale","code":"#!ek9\ndefines module error.e07155.bad\n\n  defines text for \"en\"\n    Greetings\n      hello()\n        \"Hello!\"\n\n  defines text for \"en\"\n\n    //Greetings is already defined for \"en\"\n    Greetings\n      goodbye()\n        \"Goodbye!\"","expectedOutput":null,"kind":"bad","errors":["E07155"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07155/good.ek9","url":"https://ek9.io/errors/E07155.html","title":"One text type per locale: put every method in it","code":"#!ek9\ndefines module error.e07155.good\n\n  defines text for \"en\"\n    Greetings\n      hello()\n        \"Hello!\"\n\n      goodbye()\n        \"Goodbye!\"\n\n  defines text for \"de\"\n    Greetings\n      hello()\n        \"Hallo!\"\n\n      goodbye()\n        \"Auf Wiedersehen!\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07155"}
{"id":"errors/E07156/bad.ek9","url":"https://ek9.io/errors/E07156.html","title":"E07156: 'locale' is reserved in a text construct - it names the auto-provided Locale field","code":"#!ek9\ndefines module error.e07156.bad\n\n  defines text for \"en\"\n\n    ParamNamedLocaleText\n\n      greeting()\n        -> locale as String\n        \"Fixed greeting\"\n\n    MethodNamedLocaleText\n\n      locale()\n        \"Fixed text\"","expectedOutput":null,"kind":"bad","errors":["E07156"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07156/good.ek9","url":"https://ek9.io/errors/E07156.html","title":"Choose another name: 'locale' is the text's own Locale","code":"#!ek9\ndefines module error.e07156.good\n\n  defines text for \"en\"\n\n    GreetingText\n      greeting()\n        -> language as String\n        `Hello, you asked for ${language}`\n\n      salutation()\n        \"Fixed text\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07156"}
{"id":"errors/E07160/bad.ek9","url":"https://ek9.io/errors/E07160.html","title":"E07160: implementation must be provided","code":"#!ek9\ndefines module error.e07160.bad\n\n  defines program\n\n    //Valid Program\n    NoArgument()\n      //Just some body to stop any other compiler errors\n      v <- \"Steve\"\n      require v?\n\n    //Failure1 - a program must have a body. (Its argument TYPES are checked in EXPLICIT_TYPE_SYMBOL_DEFINITION -\n    //see phase2/badPrograms/ArgumentTypeChecks.ek9 - front-end audit FE36.)\n    BadArgumentCombination()\n      ->\n        count as Integer\n        arguments as List of String","expectedOutput":null,"kind":"bad","errors":["E07160"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07160/good.ek9","url":"https://ek9.io/errors/E07160.html","title":"Give the program a body","code":"#!ek9\ndefines module error.e07160.good\n\n  defines program\n\n    //A program always has a body, even when it takes arguments\n    CountItems()\n      ->\n        name as String\n        count as Integer\n\n      stdout <- Stdout()\n      stdout.println(`${name} has ${count} items`)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07160"}
{"id":"errors/E07170/bad.ek9","url":"https://ek9.io/errors/E07170.html","title":"E07170: a developer coded constructor(s) are required where uninitialised properties are used","code":"#!ek9\ndefines module error.e07170.bad\n\n  defines class\n\n    //name is declared unset, and no constructor sets it\n    Greeter\n      name as String?\n\n      rename()\n        -> newName as String\n        name: newName\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07170"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07170/good.ek9","url":"https://ek9.io/errors/E07170.html","title":"Write a constructor that sets the property","code":"#!ek9\ndefines module error.e07170.good\n\n  defines class\n\n    Greeter\n      name as String?\n\n      default private Greeter()\n\n      Greeter()\n        -> initialName as String\n        this.name: initialName\n\n      rename()\n        -> newName as String\n        name: newName\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07170"}
{"id":"errors/E07175/bad.ek9","url":"https://ek9.io/errors/E07175.html","title":"E07175: default constructor must be 'private' when uninitialised properties exist","code":"#!ek9\ndefines module error.e07175.bad\n\n  defines class\n\n    //owner is unset until a constructor sets it, yet a public no-argument constructor is generated\n    Account\n      owner as String?\n\n      Account()\n        -> name as String\n        this.owner: name\n\n      describe() as pure\n        <- rtn as String: `Owned by ${owner}`\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07175"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07175/good.ek9","url":"https://ek9.io/errors/E07175.html","title":"Make the no-argument constructor private","code":"#!ek9\ndefines module error.e07175.good\n\n  defines class\n\n    Account\n      owner as String?\n\n      //Only the class itself can make an Account with no owner\n      default private Account()\n\n      Account()\n        -> name as String\n        this.owner: name\n\n      describe() as pure\n        <- rtn as String: `Owned by ${owner}`\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07175"}
{"id":"errors/E07176/bad.ek9","url":"https://ek9.io/errors/E07176.html","title":"E07176: a constructor cannot rely on the implicit super() - the super has no accessible no-argument constructor (it is 'private', or there is none) - call or provide an accessible initialising super constructor","code":"#!ek9\ndefines module error.e07176.bad\n\n  defines class\n\n    Reading as open\n      amount as Integer?\n\n      default private Reading()\n\n      Reading()\n        -> initial as Integer\n        this.amount: initial\n\n      default operator ?\n\n    Sample extends Reading\n      units as String?\n\n      //This constructor would run the private Reading() implicitly\n      Sample()\n        -> unitName as String\n        this.units: unitName\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07176"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07176/good.ek9","url":"https://ek9.io/errors/E07176.html","title":"Call an accessible super constructor that initialises the super","code":"#!ek9\ndefines module error.e07176.good\n\n  defines class\n\n    Reading as open\n      amount as Integer?\n\n      default private Reading()\n\n      Reading()\n        -> initial as Integer\n        this.amount: initial\n\n      default operator ?\n\n    Sample extends Reading\n      units <- String()\n\n      Sample()\n        ->\n          initial as Integer\n          unitName as String\n        super(initial)\n        this.units: unitName\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07176"}
{"id":"errors/E07177/bad.ek9","url":"https://ek9.io/errors/E07177.html","title":"E07177: the super type has no accessible no-argument constructor (it is 'private', or there is none), so a default constructor cannot be generated here - you must define a constructor for this sub-type that calls an accessible super(...)","code":"#!ek9\ndefines module error.e07177.bad\n\n  defines class\n\n    Reading as open\n      amount as Integer?\n\n      default private Reading()\n\n      Reading()\n        -> initial as Integer\n        this.amount: initial\n\n      default operator ?\n\n    //No constructor, and none can be generated: it would have to call the private Reading()\n    Sample extends Reading\n      describe()\n        <- rtn as String: \"a sample\"","expectedOutput":null,"kind":"bad","errors":["E07177"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07177/good.ek9","url":"https://ek9.io/errors/E07177.html","title":"Define a constructor that calls an accessible super(...)","code":"#!ek9\ndefines module error.e07177.good\n\n  defines class\n\n    Reading as open\n      amount as Integer?\n\n      default private Reading()\n\n      Reading()\n        -> initial as Integer\n        this.amount: initial\n\n      default operator ?\n\n    Sample extends Reading\n      Sample()\n        -> initial as Integer\n        super(initial)\n\n      describe()\n        <- rtn as String: \"a sample\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07177"}
{"id":"errors/E07180/bad.ek9","url":"https://ek9.io/errors/E07180.html","title":"E07180: 'default' of operators requires this type to have appropriate operator","code":"#!ek9\ndefines module error.e07180.bad\n\n  defines class\n\n    Reading\n      taken <- Time()\n\n      //An ordering operator is generated from '<=>', and there is none\n      default operator <\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07180"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07180/good.ek9","url":"https://ek9.io/errors/E07180.html","title":"Default '<=>' instead: the comparisons come from it","code":"#!ek9\ndefines module error.e07180.good\n\n  defines class\n\n    Reading\n      taken <- Time()\n\n      //Choose ordered sameness: '<', '<=', '>', '>=', '==' and '<>' are all generated from it\n      default operator <=>\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07180"}
{"id":"errors/E07181/bad.ek9","url":"https://ek9.io/errors/E07181.html","title":"E07181: comparisons with the type itself are generated from its sameness ('<=>' or '=='), never written or requested","code":"#!ek9\ndefines module error.e07181.bad\n\n  defines class\n\n    Person\n      id as Integer?\n\n      default private Person()\n\n      Person()\n        -> identifier as Integer\n        this.id: identifier\n\n      identity() as pure\n        <- rtn as Integer: id\n\n      operator <=> as pure\n        -> other as Person\n        <- rtn as Integer: id <=> other.identity()\n\n      operator #? as pure\n        <- rtn as Integer: #?id\n\n      override operator ? as pure\n        <- rtn as Boolean: id?\n\n      //'<' is generated from '<=>' - it is never written\n      operator < as pure\n        -> other as Person\n        <- rtn as Boolean: id < other.identity()","expectedOutput":null,"kind":"bad","errors":["E07181"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07181/good.ek9","url":"https://ek9.io/errors/E07181.html","title":"Delete it: it is generated from the sameness operator","code":"#!ek9\ndefines module error.e07181.good\n\n  defines class\n\n    Person\n      id as Integer?\n\n      default private Person()\n\n      Person()\n        -> identifier as Integer\n        this.id: identifier\n\n      identity() as pure\n        <- rtn as Integer: id\n\n      //'<' '<=' '>' '>=' '==' '<>' are all generated from this\n      operator <=> as pure\n        -> other as Person\n        <- rtn as Integer: id <=> other.identity()\n\n      operator #? as pure\n        <- rtn as Integer: #?id\n\n      override operator ? as pure\n        <- rtn as Boolean: id?\n\n  defines program\n\n    ComparePeople()\n      stdout <- Stdout()\n      first <- Person(1)\n      second <- Person(2)\n      stdout.println(`first < second: ${first < second}`)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07181"}
{"id":"errors/E07182/bad.ek9","url":"https://ek9.io/errors/E07182.html","title":"E07182: sameness ('<=>' or '==') is declared once per type hierarchy; a subtype inherits it and cannot redefine it","code":"#!ek9\ndefines module error.e07182.bad\n\n  defines class\n\n    Base as open\n      weight as Integer?\n\n      default private Base()\n\n      Base()\n        -> initial as Integer\n        this.weight: initial\n\n      default operator\n\n    Heavy extends Base\n      Heavy()\n        -> initial as Integer\n        super(initial)\n\n      //Base already declared the hierarchy's sameness\n      override operator <=> as pure\n        -> other as Base\n        <- rtn as Integer: 0","expectedOutput":null,"kind":"bad","errors":["E07182"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07182/good.ek9","url":"https://ek9.io/errors/E07182.html","title":"Inherit it","code":"#!ek9\ndefines module error.e07182.good\n\n  defines class\n\n    Base as open\n      weight as Integer?\n\n      default private Base()\n\n      Base()\n        -> initial as Integer\n        this.weight: initial\n\n      default operator\n\n    Heavy extends Base\n      Heavy()\n        -> initial as Integer\n        super(initial)\n\n      //Inherits '<=>', the comparisons and '#?' from Base\n      default operator","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07182"}
{"id":"errors/E07183/bad.ek9","url":"https://ek9.io/errors/E07183.html","title":"E07183: sameness ('<=>' or '==') must have a body where it is declared; it cannot be abstract","code":"#!ek9\ndefines module error.e07183.bad\n\n  defines trait\n\n    Ranked\n      rank() as pure\n        <- rtn as Integer?\n\n      //Sameness must say how two values compare where it is declared\n      operator <=> as pure\n        -> other as Ranked\n        <- rtn as Integer?","expectedOutput":null,"kind":"bad","errors":["E07183"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07183/good.ek9","url":"https://ek9.io/errors/E07183.html","title":"Give it a body, over abstract accessors","code":"#!ek9\ndefines module error.e07183.good\n\n  defines trait\n\n    Ranked\n      rank() as pure\n        <- rtn as Integer?\n\n      //Concrete, written over the trait's own abstract accessor\n      operator <=> as pure\n        -> other as Ranked\n        <- rtn as Integer: rank() <=> other.rank()\n\n      operator #? as pure\n        <- rtn as Integer: #?rank()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07183"}
{"id":"errors/E07184/bad.ek9","url":"https://ek9.io/errors/E07184.html","title":"E07184: '#?' goes with the type's sameness: defaulted with a defaulted one, hand-written with a hand-written one","code":"#!ek9\ndefines module error.e07184.bad\n\n  defines trait\n\n    //A trait with a concrete '==' and an abstract '#?'.\n    Coded\n      code() as pure abstract\n        <- rtn as String?\n\n      operator == as pure\n        -> other as Coded\n        <- rtn as Boolean: code() == other.code()\n\n      operator #? as pure\n        <- rtn as Integer?\n\n  defines class\n\n    //A field-less abstract root: hand-written '<=>' over an abstract accessor, abstract '#?'.\n    Shape as abstract\n      area() as pure abstract\n        <- rtn as Float?\n\n      operator <=> as pure\n        -> other as Shape\n        <- rtn as Integer: area() <=> other.area()\n\n      operator #? as pure abstract\n        <- rtn as Integer?\n\n      default operator ?\n\n    //A field-less abstract root with DEFAULTED sameness and an abstract '#?'.\n    Marker as abstract\n      default operator <=>\n\n      operator #? as pure abstract\n        <- rtn as Integer?\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07184"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07184/good.ek9","url":"https://ek9.io/errors/E07184.html","title":"Hash what it compares","code":"#!ek9\ndefines module error.e07184.good\n\n  defines class\n\n    Account\n      id as Integer?\n      balance as Integer?\n\n      default private Account()\n\n      Account()\n        ->\n          identifier as Integer\n          amount as Integer\n        this.id: identifier\n        this.balance: amount\n\n      identity() as pure\n        <- rtn as Integer: id\n\n      //Hand-written sameness...\n      operator <=> as pure\n        -> other as Account\n        <- rtn as Integer: id <=> other.identity()\n\n      //...goes with a hand-written '#?' that hashes what it compares\n      operator #? as pure\n        <- rtn as Integer: #?id\n\n      override operator ? as pure\n        <- rtn as Boolean: id? and balance?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07184"}
{"id":"errors/E07185/bad.ek9","url":"https://ek9.io/errors/E07185.html","title":"E07185: an abstract '$', '$$' or '#?' is only for a type with no fields (counting inherited ones): a sub-type's generated operator covers only its own fields, so these fields would be left out - give the operator a body, or use 'default operator' for it","code":"#!ek9\ndefines module error.e07185.bad\n\n  defines class\n\n    Shape as abstract\n      name as String: String()\n\n      //A sub-type's generated '$' would cover only its own fields, never name\n      operator $ as pure abstract\n        <- rtn as String?\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07185"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07185/good.ek9","url":"https://ek9.io/errors/E07185.html","title":"Use 'default operator $' (or give it a body)","code":"#!ek9\ndefines module error.e07185.good\n\n  defines class\n\n    Shape as abstract\n      name as String: String()\n\n      //Generated over name; a sub-type that adds fields declares its own\n      default operator $\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07185"}
{"id":"errors/E07185/good_root.ek9","url":"https://ek9.io/errors/E07185.html","title":"A field-less root may keep its '$' abstract: it has nothing to lose","code":"#!ek9\ndefines module error.e07185.good.root\n\n  defines class\n\n    Measurement as abstract\n      operator $ as pure abstract\n        <- rtn as String?\n      default operator ?\n\n    Length extends Measurement\n      metres as Float: 3.0\n      override operator $ as pure\n        <- rtn as String: `${metres}m`\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07185"}
{"id":"errors/E07190/bad.ek9","url":"https://ek9.io/errors/E07190.html","title":"E07190: 'default' of operators requires super to have appropriate operator","code":"#!ek9\ndefines module error.e07190.bad\n\n  defines class\n\n    Root as open\n      default operator ?\n\n    Holder extends Root as open\n      code as Integer: Integer()\n\n      Holder() as pure\n        -> initial as Integer\n        code :=? Integer(initial)\n\n      default operator ?\n\n    Middle extends Holder as open\n      Middle() as pure\n        -> initial as Integer\n        super(initial)\n\n    Leaf extends Middle\n      name as String: String()\n\n      Leaf() as pure\n        -> initial as Integer\n        super(initial)\n        name :=? String(\"leaf\")\n\n      default operator ?\n      default operator $\n\n    //No super class has fields: the message names the root, Plain.\n    Plain as open\n      default operator ?\n\n    PlainLeaf extends Plain\n      label as String: String()\n\n      default operator ?\n      default operator $","expectedOutput":null,"kind":"bad","errors":["E07190"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07190/good.ek9","url":"https://ek9.io/errors/E07190.html","title":"Give a super with fields the operator too","code":"#!ek9\ndefines module error.e07190.good\n\n  defines class\n\n    Root as open\n      code as Integer: Integer()\n\n      default operator ?\n      default operator $\n\n    Leaf extends Root\n      name as String: String()\n\n      default operator ?\n\n      //Root has its own '$', so the generated one can call it for Root's fields\n      default operator $","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07190"}
{"id":"errors/E07190/good_written.ek9","url":"https://ek9.io/errors/E07190.html","title":"Or write the operator by hand in the sub-type","code":"#!ek9\ndefines module error.e07190.good.written\n\n  defines class\n    Root as open\n      code as Integer: Integer()\n      codeText() as pure\n        <- rtn as String: $code\n      default operator ?\n\n    Leaf extends Root\n      name as String: String()\n      default operator ?\n      //Nothing above has '$', so Leaf writes its own instead of generating one\n      operator $ as pure\n        <- rtn as String: `${name} (${codeText()})`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07190"}
{"id":"errors/E07200/bad.ek9","url":"https://ek9.io/errors/E07200.html","title":"E07200: 'default' of operators requires property/field to have appropriate operator","code":"#!ek9\ndefines module error.e07200.bad\n\n  defines class\n\n    Sensor\n      reading <- Time()\n\n      default operator ?\n\n    Station\n      sensor <- Sensor()\n\n      //Sensor has no '$', so a generated '$' cannot convert the sensor field\n      default operator $\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07200"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07200/good.ek9","url":"https://ek9.io/errors/E07200.html","title":"Give the property type the operator","code":"#!ek9\ndefines module error.e07200.good\n\n  defines class\n\n    Sensor\n      reading <- Time()\n\n      default operator ?\n      default operator $\n\n    Station\n      sensor <- Sensor()\n\n      //Sensor now has '$', so this can be generated\n      default operator $\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07200"}
{"id":"errors/E07210/bad.ek9","url":"https://ek9.io/errors/E07210.html","title":"E07210: 'default' of operators can only support '?' operator with function delegate fields","code":"#!ek9\ndefines module error.e07210.bad\n\n  defines function\n\n    Check() as abstract\n      -> text as String\n      <- rtn as Boolean?\n\n  defines record\n\n    Rule\n      check as Check?\n\n      Rule()\n        -> callback as Check\n        this.check: callback\n\n      default operator ?\n\n      //A function cannot be compared, so '<=>' cannot be generated over it\n      default operator <=>","expectedOutput":null,"kind":"bad","errors":["E07210"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07210/good.ek9","url":"https://ek9.io/errors/E07210.html","title":"Default only '?', and write the operators over the data","code":"#!ek9\ndefines module error.e07210.good\n\n  defines function\n\n    Check() as abstract\n      -> text as String\n      <- rtn as Boolean?\n\n  defines record\n\n    Rule\n      name as String?\n      check as Check?\n\n      Rule()\n        ->\n          ruleName as String\n          callback as Check\n        this.name: ruleName\n        this.check: callback\n\n      default private Rule()\n\n      //Only '?' may be defaulted over a function delegate\n      default operator ?\n\n      //Write the sameness over the data, not the function\n      operator <=> as pure\n        -> other as Rule\n        <- rtn as Integer: name <=> other.name\n\n      operator #? as pure\n        <- rtn as Integer: #?name","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07210"}
{"id":"errors/E07220/bad.ek9","url":"https://ek9.io/errors/E07220.html","title":"E07220: 'default' is not supported on this operator","code":"#!ek9\ndefines module error.e07220.bad\n\n  defines record\n    Basket\n      items <- List() of String\n\n      //What 'empty' means is the type's own decision\n      default operator empty\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07220"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07220/good.ek9","url":"https://ek9.io/errors/E07220.html","title":"Write the operator","code":"#!ek9\ndefines module error.e07220.good\n\n  defines record\n    Basket\n      items <- List() of String\n\n      operator empty as pure\n        <- rtn as Boolean: items.empty()\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07220"}
{"id":"errors/E07230/bad.ek9","url":"https://ek9.io/errors/E07230.html","title":"E07230: 'default' with an operator must not have signature or body","code":"#!ek9\ndefines module error.e07230.bad\n\n  defines record\n    Label\n      text <- String()\n\n      //'default' generates the whole operator: no signature, no body\n      default operator $ as pure\n        <- rtn as String: text\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07230"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07230/good.ek9","url":"https://ek9.io/errors/E07230.html","title":"Either 'default operator $' alone, or the operator written without 'default'","code":"#!ek9\ndefines module error.e07230.good\n\n  defines record\n    Label\n      text <- String()\n\n      //Either generate it...\n      default operator $\n\n      //...or write it in full, without 'default'\n      operator $$ as pure\n        <- rtn as JSON: JSON(\"text\", JSON(text))\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07230"}
{"id":"errors/E07235/bad.ek9","url":"https://ek9.io/errors/E07235.html","title":"E07235: aggregate with properties/fields requires 'override operator ?' (custom) or 'default operator ?' (auto-generated) to define set/unset semantics","code":"#!ek9\ndefines module error.e07235.bad\n\n  defines class\n\n    Person\n      name <- String()\n      age <- Integer()","expectedOutput":null,"kind":"bad","errors":["E07235"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07235/good.ek9","url":"https://ek9.io/errors/E07235.html","title":"Generate it: set only when every field is set","code":"#!ek9\ndefines module error.e07235.good\n\n  defines class\n\n    Person\n      name <- String()\n      age <- Integer()\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07235"}
{"id":"errors/E07235/good_custom.ek9","url":"https://ek9.io/errors/E07235.html","title":"Write it: only the name is required","code":"#!ek9\ndefines module error.e07235.good.custom\n\n  defines class\n\n    Person\n      name <- String()\n      age <- Integer()\n\n      override operator ? as pure\n        <- rtn as Boolean: name?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07235"}
{"id":"errors/E07235/good_inherited.ek9","url":"https://ek9.io/errors/E07235.html","title":"A sub-type that adds fields declares its own","code":"#!ek9\ndefines module error.e07235.good.inherited\n\n  defines class\n\n    Person as open\n      name <- String()\n\n      default operator ?\n\n    Employee extends Person\n      employeeId <- String()\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07235"}
{"id":"errors/E07235/good_fieldless.ek9","url":"https://ek9.io/errors/E07235.html","title":"A type with no fields needs none; the sub-type that adds one does","code":"#!ek9\ndefines module error.e07235.good.fieldless\n\n  defines class\n\n    Marker as open\n      mark()\n        <- rtn as String: \"marked\"\n\n    Counted extends Marker\n      count <- Integer()\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07235"}
{"id":"errors/E07236/bad.ek9","url":"https://ek9.io/errors/E07236.html","title":"E07236: dynamic class with captured variables requires 'default operator ?' to define set/unset semantics for captured fields","code":"#!ek9\ndefines module error.e07236.bad\n\n  defines trait\n\n    Printable\n      describe() as abstract\n        <- result as String?\n\n    Formatter\n      format() as abstract\n        -> items as List of String\n        <- result as String?\n\n  defines function\n\n    testUnnamedCapture()\n      prefix <- \"Hello\"\n\n      //Single unnamed capture — prefix becomes a private field\n      printer <- (prefix) trait of Printable as class\n        override describe()\n          <- result as String: prefix\n        //Missing: default operator ?\n\n    testNamedCapture()\n      greeting <- \"Hi\"\n\n      //Named capture — greeting becomes a private field\n      printer <- Greeter(greeting) trait of Printable as class\n        override describe()\n          <- result as String: greeting\n        //Missing: default operator ?\n\n    testMultipleCaptures()\n      prefix <- \"[\"\n      suffix <- \"]\"\n\n      //Multiple captures — both become private fields\n      formatter <- (prefix, suffix) trait of Printable as class\n        override describe()\n          <- result as String: prefix + suffix\n        //Missing: default operator ?\n\n    testCaptureWithOperatorPresent()\n      prefix <- \"OK\"\n\n      //This is valid — default operator ? is defined\n      printer <- (prefix) trait of Printable as class\n        override describe()\n          <- result as String: prefix\n        default operator ?\n      require printer?\n\n    testNoCapturesNoError()\n\n      //No captures — no fields — no ? required\n      printer <- () trait of Printable as class\n        override describe()\n          <- result as String: \"static\"\n        default operator ?\n      require printer?","expectedOutput":null,"kind":"bad","errors":["E07236"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07236/good.ek9","url":"https://ek9.io/errors/E07236.html","title":"Add 'default operator ?' to the dynamic class","code":"#!ek9\ndefines module error.e07236.good\n\n  defines trait\n\n    Printable\n      describe() as abstract\n        <- result as String?\n\n  defines program\n\n    PrintGreeting()\n      stdout <- Stdout()\n      prefix <- \"Hello\"\n\n      //The capture becomes a field, so the dynamic class says when it is set\n      printer <- (prefix) trait of Printable as class\n        override describe()\n          <- result as String: prefix\n        default operator ?\n\n      stdout.println(printer.describe())","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07236"}
{"id":"errors/E07236/good_delegation.ek9","url":"https://ek9.io/errors/E07236.html","title":"With 'by' delegation the captures are fields too","code":"#!ek9\ndefines module error.e07236.good.delegation\n\n  defines trait\n\n    LengthCheck\n      longEnough() as abstract\n        -> text as String\n        <- rtn as Boolean?\n\n    CharacterCheck\n      allLetters() as abstract\n        -> text as String\n        <- rtn as Boolean?\n\n  defines class\n\n    MinimumLength with trait of LengthCheck\n      override longEnough()\n        -> text as String\n        <- rtn as Boolean: not text.empty()\n\n    Letters with trait of CharacterCheck\n      override allLetters()\n        -> text as String\n        <- rtn as Boolean: text matches /^[a-zA-Z]+$/\n\n  defines program\n\n    Validate()\n      stdout <- Stdout()\n      lengthCheck <- MinimumLength()\n      characterCheck <- Letters()\n\n      //Delegated 'by' captures: they are fields too, so '?' is defaulted\n      validator <- (lengthCheck, characterCheck) trait of LengthCheck by lengthCheck, CharacterCheck by characterCheck\n        default operator ?\n\n      stdout.println($validator.longEnough(\"Steve\"))","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07236"}
{"id":"errors/E07236/good_custom.ek9","url":"https://ek9.io/errors/E07236.html","title":"Write the '?' yourself: only some captures are required","code":"#!ek9\ndefines module error.e07236.good.custom\n\n  defines trait\n    Connectable\n      connect() as abstract\n        <- rtn as Boolean?\n\n  defines program\n    Connect()\n      stdout <- Stdout()\n      host <- \"localhost\"\n      port <- 8080\n      timeout <- Integer()\n\n      //'set' means the host and port are set; the timeout is optional\n      connection <- (host, port, timeout) trait of Connectable as class\n        override connect()\n          <- rtn as Boolean: host? and port? and (timeout? or port > 0)\n        override operator ? as pure\n          <- rtn as Boolean: host? and port?\n\n      ready <- connection?\n      stdout.println($ready)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07236"}
{"id":"errors/E07237/bad.ek9","url":"https://ek9.io/errors/E07237.html","title":"E07237: a record exists only to carry data, but this concrete record has no fields (counting inherited ones) - give it a field, make it a class or component if it carries behaviour, or mark it 'as abstract' if it is the root of a record hierarchy","code":"#!ek9\ndefines module error.e07237.bad\n\n  defines record\n\n    //A plain concrete record with nothing in it.\n    Nothing\n\n    //Operators alone do not make it carry anything.\n    OnlyOperators\n      operator $ as pure\n        <- rtn as String: \"only operators\"\n\n    //Open is not abstract: an open record with no fields can still be created, holding nothing.\n    OpenButEmpty as open\n      default operator ?\n\n    //A field-less abstract root is legal...\n    Shape as abstract\n      default operator ?\n\n    //...but a concrete sub-record of it must add the fields.\n    EmptyShape extends Shape\n\n    //Two levels down, still nothing anywhere in the hierarchy.\n    AbstractMiddle extends Shape as abstract\n      default operator ?\n\n    EmptyLeaf extends AbstractMiddle","expectedOutput":null,"kind":"bad","errors":["E07237"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07237/good.ek9","url":"https://ek9.io/errors/E07237.html","title":"Give it the data it carries","code":"#!ek9\ndefines module error.e07237.good\n\n  defines record\n\n    Reading\n      celsius <- 21.5\n      default operator","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07237"}
{"id":"errors/E07237/good_root.ek9","url":"https://ek9.io/errors/E07237.html","title":"Make a field-less root abstract","code":"#!ek9\ndefines module error.e07237.good.root\n\n  defines record\n\n    //A field-less abstract root\n    Measurement as abstract\n      default operator ?\n\n    Length extends Measurement as open\n      metres <- 3.0\n      default operator ?\n\n    //Adds no fields, but inherits metres\n    Height extends Length","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07237"}
{"id":"errors/E07238/bad.ek9","url":"https://ek9.io/errors/E07238.html","title":"E07238: a type that adds fields must declare its own '$', '$$' and ':=:' where it would inherit one: the inherited operator was written for the super's fields and cannot know these - use 'default operator $' (and likewise for the others) or write one","code":"#!ek9\ndefines module error.e07238.bad\n\n  defines record\n\n    //A record root with '$$' and ':=:'.\n    Reading as open\n      celsius as Float: Float()\n      default operator ?\n      default operator $$\n      default operator :=:\n\n    //Adds a field, declares '$$' only: it would inherit Reading's ':=:'.\n    Located extends Reading\n      place as String: String()\n      default operator ?\n      default operator $$\n\n  defines class\n\n    //A class root with every one of the three.\n    Base as open\n      id as Integer: Integer()\n      default operator ?\n      default operator $\n      default operator $$\n      default operator :=:\n\n    //Adds a field and declares only '?': it would inherit all three.\n    Leaf extends Base\n      name as String: String()\n      default operator ?\n\n    //No fields of its own: needs nothing.\n    Middle extends Base as open\n      Middle()\n        super()\n\n    //Adds a field below the field-less middle: the nearest '$' is still Base's.\n    Deeper extends Middle\n      weight as Integer: Integer()\n      default operator ?\n      default operator $$\n      default operator :=:\n\n    //A field-less root whose '$' is abstract.\n    Shape as abstract\n      operator $ as pure abstract\n        <- rtn as String?\n\n    //Adds a field but declares no '$': below an abstract one the field would be left out of every sub-type's '$'.\n    Named extends Shape as abstract\n      label as String: String()\n      default operator ?\n\n  defines component\n\n    Store as open\n      size as Integer: Integer()\n      default operator ?\n      default operator $\n\n    FileStore extends Store\n      path as String: String()\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07238"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07238/good.ek9","url":"https://ek9.io/errors/E07238.html","title":"Declare the operator where the fields are added","code":"#!ek9\ndefines module error.e07238.good\n\n  defines class\n\n    Base as open\n      id as Integer: Integer()\n      default operator ?\n      default operator $\n\n    //Adds a field, so it declares its own '$' over it\n    Leaf extends Base\n      name as String: String()\n      default operator ?\n      default operator $","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07238"}
{"id":"errors/E07238/good_written.ek9","url":"https://ek9.io/errors/E07238.html","title":"Or write the operator by hand when not every field should be shown","code":"#!ek9\ndefines module error.e07238.good.written\n\n  defines class\n    Base as open\n      id as Integer: Integer()\n      default operator ?\n      default operator $\n\n    Leaf extends Base\n      name as String: String()\n      default operator ?\n\n      //Shows the name only, by choice\n      override operator $ as pure\n        <- rtn as String: `Leaf ${name}`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07238"}
{"id":"errors/E07240/bad.ek9","url":"https://ek9.io/errors/E07240.html","title":"E07240: non web service methods cannot be marked with the 'protected' access modifier","code":"#!ek9\ndefines module error.e07240.bad\n\n  defines service\n\n    Site for :/site open\n\n      index() as GET for :/\n        <- response as HTTPResponse?\n        body <- pageBody()\n        response: (body) with trait HTTPResponse\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(body)\n          override status() as pure\n            <- rtn as Integer: 200\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          override cacheControl() as pure\n            <- rtn as String: \"no-cache\"\n          override contentLanguage() as pure\n            <- rtn as String: \"en\"\n          default operator ?\n\n      //A service is never extended, so 'protected' means nothing here\n      protected pageBody()\n        <- rtn as String: \"welcome\"","expectedOutput":null,"kind":"bad","errors":["E07240"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07240/good.ek9","url":"https://ek9.io/errors/E07240.html","title":"Make the helper private","code":"#!ek9\ndefines module error.e07240.good\n\n  defines service\n\n    Site for :/site open\n\n      index() as GET for :/\n        <- response as HTTPResponse?\n        body <- pageBody()\n        response: (body) with trait HTTPResponse\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(body)\n          override status() as pure\n            <- rtn as Integer: 200\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          override cacheControl() as pure\n            <- rtn as String: \"no-cache\"\n          override contentLanguage() as pure\n            <- rtn as String: \"en\"\n          default operator ?\n\n      //A helper only the service calls is private\n      private pageBody()\n        <- rtn as String: \"welcome\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07240"}
{"id":"errors/E07250/bad.ek9","url":"https://ek9.io/errors/E07250.html","title":"E07250: component methods cannot be marked with the 'protected' access modifier","code":"#!ek9\ndefines module error.e07250.bad\n\n  defines component\n\n    Store\n      fetch()\n        -> key as String\n        <- rtn as String: normalise(key)\n\n      //A component is never extended, so 'protected' means nothing here\n      protected normalise()\n        -> key as String\n        <- rtn as String: key.trim()","expectedOutput":null,"kind":"bad","errors":["E07250"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07250/good.ek9","url":"https://ek9.io/errors/E07250.html","title":"Make it private (or public)","code":"#!ek9\ndefines module error.e07250.good\n\n  defines component\n\n    Store\n      fetch()\n        -> key as String\n        <- rtn as String: normalise(key)\n\n      private normalise()\n        -> key as String\n        <- rtn as String: key.trim()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07250"}
{"id":"errors/E07260/bad.ek9","url":"https://ek9.io/errors/E07260.html","title":"E07260: class methods can only be marked with the 'protected' access modifier in classes that are 'open'","code":"#!ek9\ndefines module error.e07260.bad\n\n  defines class\n\n    //Closed by default: there are no sub-classes to protect a method for\n    Greeter\n      greet()\n        <- rtn as String: salutation()\n\n      protected salutation()\n        <- rtn as String: \"hello\"","expectedOutput":null,"kind":"bad","errors":["E07260"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07260/good.ek9","url":"https://ek9.io/errors/E07260.html","title":"Make it private, or open the class","code":"#!ek9\ndefines module error.e07260.good\n\n  defines class\n\n    //Option 1: keep it closed, and make the method private\n    Greeter\n      greet()\n        <- rtn as String: salutation()\n\n      private salutation()\n        <- rtn as String: \"hello\"\n\n    //Option 2: open the class, so sub-classes may use the protected method\n    OpenGreeter as open\n      greet()\n        <- rtn as String: salutation()\n\n      protected salutation()\n        <- rtn as String: \"hello\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07260"}
{"id":"errors/E07270/bad.ek9","url":"https://ek9.io/errors/E07270.html","title":"E07270: trait methods cannot be marked with an access modifier, they are always public","code":"#!ek9\ndefines module error.e07270.bad\n\n  defines trait\n\n    Formatter\n      format()\n        -> amount as Integer\n        <- rtn as String: prefix() + $amount\n\n      //Every trait method is public\n      private prefix()\n        <- rtn as String: \"#\"","expectedOutput":null,"kind":"bad","errors":["E07270"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07270/good.ek9","url":"https://ek9.io/errors/E07270.html","title":"Remove the access modifier","code":"#!ek9\ndefines module error.e07270.good\n\n  defines trait\n\n    Formatter\n      format()\n        -> amount as Integer\n        <- rtn as String: prefix() + $amount\n\n      prefix()\n        <- rtn as String: \"#\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07270"}
{"id":"errors/E07280/bad.ek9","url":"https://ek9.io/errors/E07280.html","title":"E07280: access modifier is not needed here - methods are 'public' by default","code":"#!ek9\ndefines module error.e07280.bad\n\n  defines class\n\n    Greeter\n      //Methods are public unless marked otherwise\n      public greet()\n        <- rtn as String: \"hello\"","expectedOutput":null,"kind":"bad","errors":["E07280"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07280/good.ek9","url":"https://ek9.io/errors/E07280.html","title":"Remove 'public': it is the default","code":"#!ek9\ndefines module error.e07280.good\n\n  defines class\n\n    Greeter\n      //Public, with no modifier\n      greet()\n        <- rtn as String: salutation()\n\n      //A modifier is written only to narrow access\n      private salutation()\n        <- rtn as String: \"hello\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07280"}
{"id":"errors/E07290/bad.ek9","url":"https://ek9.io/errors/E07290.html","title":"E07290: only constructors and operators methods are supported on records","code":"#!ek9\ndefines module error.e07290.bad\n\n  defines record\n\n    Point\n      x <- 0\n      y <- 0\n\n      //A record carries data; behaviour belongs in a function or a class\n      moveBy()\n        -> distance as Integer\n        <- rtn as Point: Point(x + distance, y + distance)\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07290"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07290/good.ek9","url":"https://ek9.io/errors/E07290.html","title":"Use an operator, or a function over the record","code":"#!ek9\ndefines module error.e07290.good\n\n  defines record\n\n    Point\n      x as Integer?\n      y as Integer?\n\n      default private Point() as pure\n\n      Point() as pure\n        ->\n          across as Integer\n          down as Integer\n        this.x :=? across\n        this.y :=? down\n\n      //Operators are allowed on a record\n      operator + as pure\n        -> other as Point\n        <- rtn as Point: Point(x + other.x, y + other.y)\n\n      default operator ?\n\n  defines function\n\n    //The behaviour is a function over the record\n    moveBy() as pure\n      ->\n        point as Point\n        distance as Integer\n      <- rtn as Point: point + Point(distance, distance)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07290"}
{"id":"errors/E07300/bad.ek9","url":"https://ek9.io/errors/E07300.html","title":"E07300: declaration supporting 'uninitialised' is not needed","code":"#!ek9\ndefines module error.e07300.bad\n\n  defines class\n\n    Holder\n      prop as String? : \"p\"\n\n      default operator ?\n\n  defines function\n\n    returnWithAValue()\n      <- rtn as String? : String()\n      rtn: \"x\"\n\n    localViaAssign()\n      <- rtn as String: String()\n      label as String? := \"x\"\n      rtn: label\n\n    localViaEquals()\n      <- rtn as String: String()\n      label as String? = \"x\"\n      rtn: label\n\n    localViaMerge()\n      <- rtn as String: String()\n      label as String? :~: \"x\"\n      rtn: label\n\n    //Both forms that ARE meant - a value, or no value yet - stay as they were.\n    stillFine()\n      <- rtn as String: String()\n      label as String: \"x\"\n      pending as String?\n      pending: label\n      rtn: pending","expectedOutput":null,"kind":"bad","errors":["E07300"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07300/good.ek9","url":"https://ek9.io/errors/E07300.html","title":"Write '?' only where there is no value yet","code":"#!ek9\ndefines module error.e07300.good\n\n  defines function\n\n    //A value: no '?'\n    withAValue()\n      <- rtn as String: \"x\"\n\n    //No value yet: the '?' says so, and it is assigned later\n    noValueYet()\n      <- rtn as String: String()\n      pending as String?\n      pending: \"x\"\n      rtn: pending","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07300"}
{"id":"errors/E07310/bad.ek9","url":"https://ek9.io/errors/E07310.html","title":"E07310: 'cases' should cover all enumerated values in 'switch'","code":"#!ek9\ndefines module error.e07310.bad\n\n  defines type\n\n    Signal\n      Red\n      Amber\n      Green\n\n  defines function\n\n    meaning()\n      -> signal as Signal\n      <- rtn as String: String()\n\n      //Amber and Green are not handled\n      description <- switch signal\n        <- text as String: \"unknown\"\n        case Signal.Red\n          text: \"stop\"\n        default\n          text: \"not set\"\n\n      rtn: description","expectedOutput":null,"kind":"bad","errors":["E07310"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07310/good.ek9","url":"https://ek9.io/errors/E07310.html","title":"Handle every value, and the unset one","code":"#!ek9\ndefines module error.e07310.good\n\n  defines type\n\n    Signal\n      Red\n      Amber\n      Green\n\n  defines function\n\n    meaning()\n      -> signal as Signal\n      <- rtn as String: String()\n\n      //Every value is handled, and the default handles an unset signal\n      description <- switch signal\n        <- text as String: \"unknown\"\n        case Signal.Red\n          text: \"stop\"\n        case Signal.Amber\n          text: \"wait\"\n        case Signal.Green\n          text: \"go\"\n        default\n          text: \"not set\"\n\n      rtn: description","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07310"}
{"id":"errors/E07320/bad.ek9","url":"https://ek9.io/errors/E07320.html","title":"E07320: 'default' is required in this 'switch' statement","code":"#!ek9\ndefines module error.e07320.bad\n\n  defines function\n\n    allCasesThrowNoDefault()\n      -> val as String\n      <- rtn as String: \"start\"\n\n      switch val\n        case \"This\"\n          throw Exception(\"This\")\n        case \"That\"\n          throw Exception(\"That\")\n\n      rtn += \"!\"","expectedOutput":null,"kind":"bad","errors":["E07320"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07320/good.ek9","url":"https://ek9.io/errors/E07320.html","title":"Add a default","code":"#!ek9\ndefines module error.e07320.good\n\n  defines function\n\n    describe()\n      -> word as String\n      <- rtn as String: \"start\"\n\n      //A default handles every other value, and an unset one\n      switch word\n        case \"This\"\n          rtn: \"this\"\n        case \"That\"\n          rtn: \"that\"\n        default\n          rtn: \"something else\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07320"}
{"id":"errors/E07330/bad.ek9","url":"https://ek9.io/errors/E07330.html","title":"E07330: 'default' is required in this 'switch' expression","code":"#!ek9\ndefines module error.e07330.bad\n\n  defines function\n\n    sizeOf()\n      -> count as Integer\n      <- rtn as String: String()\n\n      //Without a default, size has no value when count is 10 or more, or unset\n      size <- switch count\n        <- text as String?\n        case < 10\n          text: \"small\"\n\n      rtn: size","expectedOutput":null,"kind":"bad","errors":["E07330"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07330/good.ek9","url":"https://ek9.io/errors/E07330.html","title":"Add a default","code":"#!ek9\ndefines module error.e07330.good\n\n  defines function\n\n    sizeOf()\n      -> count as Integer\n      <- rtn as String: String()\n\n      size <- switch count\n        <- text as String: String()\n        case < 10\n          text: \"small\"\n        default\n          text: \"large\"\n\n      rtn: size","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07330"}
{"id":"errors/E07340/bad.ek9","url":"https://ek9.io/errors/E07340.html","title":"E07340: without a control, failed to find subject of flow","code":"#!ek9\ndefines module error.e07340.bad\n\n  defines function\n\n    findItem()\n      <- rtn as String: \"found\"\n\n    blindAssignmentWithNoControl()\n      <- rtn as String: String()\n      selectedItem <- String()\n      if selectedItem := findItem()\n        rtn: selectedItem\n\n    blindAssignmentInElseIfWithNoControl()\n      -> flag as Boolean\n      <- rtn as String: String()\n      selectedItem <- String()\n      if flag\n        rtn: \"flag\"\n      else if selectedItem := findItem()\n        rtn: selectedItem\n\n    typedDeclarationWithNoControl()\n      <- rtn as String: String()\n      if selectedItem as String: findItem()\n        rtn: selectedItem\n\n    compoundAssignmentWithNoControl()\n      <- rtn as String: String()\n      counter <- 1\n      when counter += 2\n        rtn: $counter\n\n    blindAssignmentWithControlIsValid()\n      <- rtn as String: String()\n      selectedItem <- String()\n      if selectedItem := findItem() with selectedItem?\n        rtn: selectedItem\n\n    guardsWithNoControlAreValid()\n      <- rtn as String: String()\n      existing <- String()\n      if fresh <- findItem()\n        rtn: fresh\n      if existing := findItem() then existing?\n        rtn: existing\n      if existing :=? findItem()\n        rtn: existing","expectedOutput":null,"kind":"bad","errors":["E07340"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07340/good.ek9","url":"https://ek9.io/errors/E07340.html","title":"Use a guard, or say what to test","code":"#!ek9\ndefines module error.e07340.good\n\n  defines function\n\n    findItem()\n      <- rtn as String: \"found\"\n\n    //A declaration guard: the body runs only when found is set\n    withAGuard()\n      <- rtn as String: String()\n      if found <- findItem()\n        rtn: found\n\n    //An assignment needs a control saying what to test\n    withAControl()\n      <- rtn as String: String()\n      selectedItem <- String()\n      if selectedItem := findItem() then selectedItem?\n        rtn: selectedItem","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07340"}
{"id":"errors/E07360/bad.ek9","url":"https://ek9.io/errors/E07360.html","title":"E07360: application selection not allowed in this context","code":"#!ek9\ndefines module error.e07360.bad\n\n  defines component\n\n    Greeting as abstract\n      message() as abstract\n        <- rtn as String?\n\n    EnglishGreeting extends Greeting\n      override message()\n        <- rtn as String: \"hello\"\n\n  defines application\n\n    GreeterApp\n      register EnglishGreeting() as Greeting\n\n  defines class\n\n    Greeter\n\n      //Only a program selects an application\n      greet() with application of GreeterApp\n        <- rtn as String: \"hello\"","expectedOutput":null,"kind":"bad","errors":["E07360"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07360/good.ek9","url":"https://ek9.io/errors/E07360.html","title":"Select the application on a program","code":"#!ek9\ndefines module error.e07360.good\n\n  defines component\n\n    Greeting as abstract\n      message() as abstract\n        <- rtn as String?\n\n    EnglishGreeting extends Greeting\n      override message()\n        <- rtn as String: \"hello\"\n\n  defines application\n\n    GreeterApp\n      register EnglishGreeting() as Greeting\n\n  defines program\n\n    //A program selects the application, and is given what it registers\n    Greet() with application of GreeterApp\n      greeting as Greeting!\n      stdout <- Stdout()\n      stdout.println(greeting.message())","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07360"}
{"id":"errors/E07370/bad.ek9","url":"https://ek9.io/errors/E07370.html","title":"E07370: all paths lead to an Exception","code":"#!ek9\ndefines module error.e07370.bad\n\n  defines function\n\n    printAll()\n      //The loop body always throws, so the loop can never go round a second time\n      for item in [\"Alpha\", \"Beta\", \"Charlie\"]\n        throw Exception(\"This will always fail\")","expectedOutput":null,"kind":"bad","errors":["E07370"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07370/good.ek9","url":"https://ek9.io/errors/E07370.html","title":"Throw only when something is wrong","code":"#!ek9\ndefines module error.e07370.good\n\n  defines function\n\n    printAll()\n      stdout <- Stdout()\n      for item in [\"Alpha\", \"Beta\", \"Charlie\"]\n        if item == \"Beta\"\n          throw Exception(\"Only fails for Beta\")\n        stdout.println(item)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07370"}
{"id":"errors/E07380/bad.ek9","url":"https://ek9.io/errors/E07380.html","title":"E07380: return not possible, as instructions only result in an Exception","code":"#!ek9\ndefines module error.e07380.bad\n\n  defines function\n\n    blockBodyOnlyThrows()\n      <- rtn as Boolean?\n      supplier <- () is Supplier of String as pure function\n        throw Exception(\"always\")\n      rtn: supplier?\n\n    singleStatementBodyOnlyThrows()\n      <- rtn as Boolean?\n      supplier <- () is Supplier of String as pure function (throw Exception(\"always\"))\n      rtn: supplier?\n\n    everyBranchThrows()\n      <- rtn as Boolean?\n      describer <- () is Function of (Integer, String) as pure function\n        if t > 0\n          throw Exception(\"positive\")\n        else\n          throw Exception(\"not positive\")\n      rtn: describer?\n\n    oneBranchReturnsIsFine()\n      <- rtn as Boolean?\n      describer <- () is Function of (Integer, String) as pure function\n        if t > 0\n          throw Exception(\"positive\")\n        else\n          r: \"not positive\"\n      rtn: describer?\n\n    voidSuperMayOnlyThrow()\n      <- rtn as Boolean?\n      consumer <- () is Consumer of String as pure function\n        throw Exception(\"always\")\n      rtn: consumer?","expectedOutput":null,"kind":"bad","errors":["E07380"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07380/good.ek9","url":"https://ek9.io/errors/E07380.html","title":"Give at least one path a value to return","code":"#!ek9\ndefines module error.e07380.good\n\n  defines program\n\n    Describe()\n      stdout <- Stdout()\n\n      //One branch gives the result a value, so it can be returned\n      describer <- () is Function of (Integer, String) as pure function\n        if t > 0\n          throw Exception(\"positive\")\n        else\n          r: \"not positive\"\n\n      stdout.println(describer(0))","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07380"}
{"id":"errors/E07390/bad.ek9","url":"https://ek9.io/errors/E07390.html","title":"E07390: constant Boolean literal in expression is pointless","code":"#!ek9\ndefines module error.e07390.bad\n\n  defines function\n\n    parenthesised()\n      -> amount as Integer\n      <- rtn as Integer: amount\n      if (false)\n        rtn: 1\n      while (true)\n        rtn++\n\n    negatedOrNested()\n      -> amount as Integer\n      <- rtn as Integer: amount\n      if not false\n        rtn: 1\n      while ((false))\n        rtn++","expectedOutput":null,"kind":"bad","errors":["E07390"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07390/good.ek9","url":"https://ek9.io/errors/E07390.html","title":"Use a condition that can change","code":"#!ek9\ndefines module error.e07390.good\n\n  defines function\n\n    countDown()\n      -> amount as Integer\n      <- rtn as Integer: amount\n\n      //A condition that can be either true or false\n      while rtn > 0\n        rtn--","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07390"}
{"id":"errors/E07395/bad.ek9","url":"https://ek9.io/errors/E07395.html","title":"E07395: 'Void' has no accessible methods or operators","code":"#!ek9\ndefines module error.e07395.bad\n\n  defines function\n\n    process()\n      value <- 1\n      require value?\n\n  defines program\n\n    //'process()' returns nothing (Void), so '?' has no meaningful receiver.\n    BadIfVoidIsSet()\n      stdout <- Stdout()\n\n      if process()?\n        stdout.println(\"never runs\")\n\n    //The same pointlessness via an assert condition.\n    BadAssertVoidIsSet()\n      assert process()?","expectedOutput":null,"kind":"bad","errors":["E07395"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07395/good.ek9","url":"https://ek9.io/errors/E07395.html","title":"Call it as a statement, or return a value to test","code":"#!ek9\ndefines module error.e07395.good\n\n  defines function\n\n    process()\n      stdout <- Stdout()\n      stdout.println(\"processing\")\n\n    countItems()\n      <- rtn as Integer: 3\n\n  defines program\n\n    //Option 1: only the side effect is needed, so just call it\n    CallIt()\n      process()\n\n    //Option 2: return a value, and test that\n    TestAValue()\n      stdout <- Stdout()\n      if count <- countItems()\n        stdout.println(`${count} items`)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07395"}
{"id":"errors/E07400/bad.ek9","url":"https://ek9.io/errors/E07400.html","title":"E07400: returning variable and type missing","code":"#!ek9\ndefines module error.e07400.bad\n\n  defines class\n\n    Counter\n      count <- 0\n\n      //'!' produces a value, so it must declare what it returns\n      operator ! as pure\n        total <- count\n        require total?\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07400"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07400/good.ek9","url":"https://ek9.io/errors/E07400.html","title":"Declare the returning variable","code":"#!ek9\ndefines module error.e07400.good\n\n  defines class\n\n    Counter\n      count <- 0\n\n      operator ! as pure\n        <- rtn as Integer: count\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07400"}
{"id":"errors/E07405/bad.ek9","url":"https://ek9.io/errors/E07405.html","title":"E07405: returning block required for assignment to 'lhs' when used in expression","code":"#!ek9\ndefines module error.e07405.bad\n\n  defines function\n\n    describe()\n      -> word as String\n      stdout <- Stdout()\n\n      //A switch assigned to a variable must declare what it returns\n      description <- switch word\n        case \"ToCheck\"\n          stdout.println(\"Jackpot\")\n        default\n          stdout.println(\"Nothing\")","expectedOutput":null,"kind":"bad","errors":["E07405"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07405/good.ek9","url":"https://ek9.io/errors/E07405.html","title":"Declare the returning variable inside the switch","code":"#!ek9\ndefines module error.e07405.good\n\n  defines function\n\n    describe()\n      -> word as String\n      <- rtn as String: String()\n\n      description <- switch word\n        <- text as String: String()\n        case \"ToCheck\"\n          text: \"Jackpot\"\n        default\n          text: \"Nothing\"\n\n      rtn: description","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07405"}
{"id":"errors/E07406/bad.ek9","url":"https://ek9.io/errors/E07406.html","title":"E07406: returning block is not required as there is no 'lhs' variable to assign it to","code":"#!ek9\ndefines module error.e07406.bad\n\n  defines function\n\n    describe()\n      -> word as String\n      <- rtn as String: String()\n\n      //Nothing receives the switch's value\n      switch word\n        <- text as String: String()\n        case \"ToCheck\"\n          rtn: \"Jackpot\"\n        default\n          rtn: \"Nothing\"","expectedOutput":null,"kind":"bad","errors":["E07406"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07406/good.ek9","url":"https://ek9.io/errors/E07406.html","title":"Remove the returning declaration from a switch statement","code":"#!ek9\ndefines module error.e07406.good\n\n  defines function\n\n    describe()\n      -> word as String\n      <- rtn as String: String()\n\n      //A switch statement: no returning variable\n      switch word\n        case \"ToCheck\"\n          rtn: \"Jackpot\"\n        default\n          rtn: \"Nothing\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07406"}
{"id":"errors/E07410/bad.ek9","url":"https://ek9.io/errors/E07410.html","title":"E07410: returning type must be same as the construct type","code":"#!ek9\ndefines module error.e07410.bad\n\n  defines class\n\n    Toggle\n      on <- false\n\n      //'~' returns the type it is declared on, never another\n      operator ~ as pure\n        <- rtn as Boolean: not on\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07410"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07410/good.ek9","url":"https://ek9.io/errors/E07410.html","title":"Return the type that declares the operator","code":"#!ek9\ndefines module error.e07410.good\n\n  defines class\n\n    Toggle\n      on as Boolean?\n\n      default private Toggle() as pure\n\n      Toggle() as pure\n        -> initial as Boolean\n        this.on :=? initial\n\n      //'~' returns the type it is declared on\n      operator ~ as pure\n        <- rtn as Toggle: Toggle(not on)\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07410"}
{"id":"errors/E07420/bad.ek9","url":"https://ek9.io/errors/E07420.html","title":"E07420: returning type must not be same for promotion","code":"#!ek9\ndefines module error.e07420.bad\n\n  defines class\n\n    Celsius\n      degrees <- 0.0\n\n      //Promotion converts to ANOTHER type\n      operator #^ as pure\n        <- rtn as Celsius: this\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07420"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07420/good.ek9","url":"https://ek9.io/errors/E07420.html","title":"Promote to a different type","code":"#!ek9\ndefines module error.e07420.good\n\n  defines class\n\n    Celsius\n      degrees <- 0.0\n\n      operator #^ as pure\n        <- rtn as Float: degrees\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07420"}
{"id":"errors/E07430/bad.ek9","url":"https://ek9.io/errors/E07430.html","title":"E07430: return not required/supported in this context","code":"#!ek9\ndefines module error.e07430.bad\n\n  defines class\n\n    Wallet\n      amount <- 0.0\n\n      holding() as pure\n        <- rtn as Float: amount\n\n      //Copy changes this object in place; it returns nothing\n      operator :=:\n        -> other as Wallet\n        <- rtn as Float: other.holding()\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07430"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07430/good.ek9","url":"https://ek9.io/errors/E07430.html","title":"Remove the returning declaration","code":"#!ek9\ndefines module error.e07430.good\n\n  defines class\n\n    Wallet\n      amount <- 0.0\n\n      holding() as pure\n        <- rtn as Float: amount\n\n      operator :=:\n        -> other as Wallet\n        amount :=: other.holding()\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07430"}
{"id":"errors/E07440/bad.ek9","url":"https://ek9.io/errors/E07440.html","title":"E07440: return types are incompatible (covariance required)","code":"#!ek9\ndefines module error.e07440.bad\n\n  <?-\n    Just use these for valid covariance checks.\n  -?>\n  defines record\n\n    R1 as open\n      someField <- \"Field1\"\n\n      default operator ?\n\n    R2 extends R1\n      anotherField <- \"Field2\"\n\n      default operator ?\n\n    <?-\n      Something that is unrelated to R1 or R2.\n      To be used later in tests.\n    -?>\n    R3\n      unrelatedField <- \"Field3\"\n\n      default operator ?\n\n  defines class\n\n    C1 as open\n      someMethod1()\n        -> text as String\n        <- rtn as Float: 1.0\n\n      someMethod2()\n        -> text as String\n        <- rtn as R1: R1()\n\n      someMethod3()\n        -> text as String\n        <- rtn as R1: R1()\n\n      //Something that has no return mainValue to be used in covariance checks later\n      someMethod4()\n        -> text as String\n        require text?\n\n    <?-\n      Extend an override the C1 someMethod1 method but alter the return type\n      so that it incompatible with the class C1\n    -?>\n    C2 extends C1\n      override someMethod1()\n        -> text as String\n        <- rtn as String: \"Test\"\n\n      <?-\n        just a normal override no covariance issues or use.\n      -?>\n      override someMethod2()\n        -> text as String\n        <- rtn as R1: R1()\n\n      <?-\n        Again override and should be OK because this is valid as it is a 'R1'.\n        But this does not test covariance!\n      -?>\n      override someMethod3()\n        -> text as String\n        <- rtn as R1: R2()\n\n      <?-\n        A valid override of a method\n      -?>\n      override someMethod4()\n        -> text as String\n        require text?\n\n    <?-\n      Now even though an Integer can be coerced to a Float - it is not 'covariant'.\n    -?>\n    C3 extends C1\n      override someMethod1()\n        -> text as String\n        <- rtn as Integer: 1\n\n      <?-\n        Again override and should be OK because this is valid covariance.\n        Note that we have altered the return type.\n      -?>\n      override someMethod2()\n        -> text as String\n        <- rtn as R2: R2()\n\n      <?-\n        But R3 is not a 'R1' and therefore this is not valid covariance.\n      -?>\n      override someMethod3()\n        -> text as String\n        <- rtn as R3: R3()\n\n      <?-\n        Cannot start adding return types when super is not returning anything.\n      -?>\n      override someMethod4()\n        -> text as String\n        <- rtn as R3: R3()\n        require text?\n\n    C4 extends C1\n      <?-\n        Normal valid override\n      -?>\n      override someMethod1()\n        -> text as String\n        <- rtn as Float: 1.0\n\n      <?-\n        Must return a covariant compatible type.\n      -?>\n      override someMethod2()\n        -> text as String\n        require text?\n\n      <?-\n        But Integer '9' is not a 'R1' and therefore this is not valid covariance.\n      -?>\n      override someMethod3()\n        -> text as String\n        <- rtn <- 9\n\n      <?-\n        Another valid override\n      -?>\n      override someMethod4()\n        -> text as String\n        require text?","expectedOutput":null,"kind":"bad","errors":["E07440"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07440/good.ek9","url":"https://ek9.io/errors/E07440.html","title":"Return the super's type, or a sub-type of it","code":"#!ek9\ndefines module error.e07440.good\n\n  defines record\n\n    Shape as open\n      name <- \"shape\"\n      default operator ?\n\n    Square extends Shape\n      side <- 2\n      default operator ?\n\n  defines class\n\n    Factory as open\n      make()\n        <- rtn as Shape: Shape()\n\n    //Covariant: a Square IS a Shape\n    SquareFactory extends Factory\n      override make()\n        <- rtn as Square: Square()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07440"}
{"id":"errors/E07450/bad.ek9","url":"https://ek9.io/errors/E07450.html","title":"E07450: function must have no parameters","code":"#!ek9\ndefines module error.e07450.bad\n\n  defines function\n\n    howMany()\n      -> count as Integer\n      <- rtn as Integer: count\n\n    firstOnes()\n      collection <- List() of String\n\n      //head calls the function with no arguments\n      cat [\"last\", \"first\"] | head howMany > collection","expectedOutput":null,"kind":"bad","errors":["E07450"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07450/good.ek9","url":"https://ek9.io/errors/E07450.html","title":"Give head a function that takes no parameters","code":"#!ek9\ndefines module error.e07450.good\n\n  defines function\n\n    howMany()\n      <- rtn as Integer: 1\n\n    firstOnes()\n      <- rtn as List of String: List()\n      cat [\"last\", \"first\"] | head howMany > rtn","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07450"}
{"id":"errors/E07460/bad.ek9","url":"https://ek9.io/errors/E07460.html","title":"E07460: function must have a single parameter","code":"#!ek9\ndefines module error.e07460.bad\n\n  defines function\n\n    justACouple()\n      <- rtn as Integer: 2\n\n    distinctNumbers()\n      <- rtn as List of Integer: List()\n\n      //uniq calls the function with each item\n      cat [4, 3, 3, 4, 1] | uniq justACouple > rtn","expectedOutput":null,"kind":"bad","errors":["E07460"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07460/good.ek9","url":"https://ek9.io/errors/E07460.html","title":"Give uniq a function of one parameter","code":"#!ek9\ndefines module error.e07460.good\n\n  defines function\n\n    keyOf()\n      -> number as Integer\n      <- rtn as Integer: number\n\n    distinctNumbers()\n      <- rtn as List of Integer: List()\n      cat [4, 3, 3, 4, 1] | uniq keyOf > rtn","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07460"}
{"id":"errors/E07470/bad.ek9","url":"https://ek9.io/errors/E07470.html","title":"E07470: function must have a two parameters","code":"#!ek9\ndefines module error.e07470.bad\n\n  defines function\n\n    byLength()\n      -> word as String\n      <- rtn as Integer: length word\n\n    sortWords()\n      <- rtn as List of String: List()\n\n      //sort compares two items at a time\n      cat [\"three\", \"one\", \"seven\"] | sort byLength > rtn","expectedOutput":null,"kind":"bad","errors":["E07470"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07470/good.ek9","url":"https://ek9.io/errors/E07470.html","title":"Give sort a function of two parameters","code":"#!ek9\ndefines module error.e07470.good\n\n  defines function\n\n    byLength()\n      ->\n        first as String\n        second as String\n      <- rtn as Integer: length first <=> length second\n\n    sortWords()\n      <- rtn as List of String: List()\n      cat [\"three\", \"one\", \"seven\"] | sort byLength > rtn","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07470"}
{"id":"errors/E07480/bad.ek9","url":"https://ek9.io/errors/E07480.html","title":"E07480: is not a function delegate","code":"#!ek9\ndefines module error.e07480.bad\n\n  defines class\n\n    <?-\n      A totally un-constrained generic type where T could be anything (as long as it has the ? operator).\n      So pretty much a normal generic type. But in this case I plan to use T with a function.\n    -?>\n    UnConstrained of type T\n      default UnConstrained()\n\n      default UnConstrained()\n        -> item as T\n\n      check() as pure\n        -> item as T\n        <- rtn as Boolean: item?\n\n      //But this you cannot do, you cannot use T as both a possible aggregate and a possible function delegate.\n      call() as pure\n        ->\n          item as T\n          input as String\n        <- rtn as Boolean: item(input)\n\n\n  defines function\n\n    <?-\n      Function can be used directly or as a signature for polymorphism.\n    -?>\n    SomeFunction() as open\n      -> text as String\n      <- rtn as Boolean: text?\n\n    <?-\n      Extend SomeFunction and alter implementation.\n    -?>\n    AnotherFunction is SomeFunction\n      -> text as String\n      <- rtn as Boolean: true\n\n    <?-\n      Higher order function that returns 'SomeFunction', but actually gives a Function that extends 'SomeFunction'.\n    -?>\n    getSomeFunction()\n      <- rtn as SomeFunction: AnotherFunction\n\n    <?-\n      Now strangely this will work, because a Function can be checked for non-nullness with a build in operator of ?\n      So it really only makes sense to have generics that are collections that can hold things like functions.\n      Unlike classes where it is possible to undertaken operations using the 'T'.\n    -?>\n    UseOfGenericClassWithFunctionDemo1()\n      demo <- UnConstrained() of SomeFunction\n\n      result1 <- demo.check(SomeFunction)\n      require result1\n\n      //Call a higher function to return a function.\n      result2 <- demo.check(getSomeFunction())\n      require result2","expectedOutput":null,"kind":"bad","errors":["E07480"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07480/good.ek9","url":"https://ek9.io/errors/E07480.html","title":"Call a value whose type is a function","code":"#!ek9\ndefines module error.e07480.good\n\n  defines function\n\n    Check() as abstract\n      -> text as String\n      <- rtn as Boolean?\n\n    notEmpty() is Check\n      -> text as String\n      <- rtn as Boolean: text?\n\n  defines class\n\n    Checker\n      //check is a function delegate, so it can be called\n      run()\n        ->\n          check as Check\n          input as String\n        <- rtn as Boolean: check(input)\n\n  defines program\n\n    RunCheck()\n      stdout <- Stdout()\n      stdout.println($Checker().run(notEmpty, \"Steve\"))","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07480"}
{"id":"errors/E07490/bad.ek9","url":"https://ek9.io/errors/E07490.html","title":"E07490: function must return a value","code":"#!ek9\ndefines module error.e07490.bad\n\n  defines function\n\n    sayHello()\n      stdout <- Stdout()\n      stdout.println(\"hello\")\n\n    greetAll()\n      stdout <- Stdout()\n\n      //call passes on what each function returns, and sayHello returns nothing\n      cat [sayHello] | call > stdout","expectedOutput":null,"kind":"bad","errors":["E07490"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07490/good.ek9","url":"https://ek9.io/errors/E07490.html","title":"Call functions that return a value","code":"#!ek9\ndefines module error.e07490.good\n\n  defines function\n\n    greeting()\n      <- rtn as String: \"hello\"\n\n    greetAll()\n      stdout <- Stdout()\n      cat [greeting] | call > stdout","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07490"}
{"id":"errors/E07500/bad.ek9","url":"https://ek9.io/errors/E07500.html","title":"E07500: operator must be declared pure","code":"#!ek9\ndefines module error.e07500.bad\n\n  defines class\n\n    Basket\n      items <- [\"apple\", \"pear\"]\n\n      //A query operator must not change anything\n      operator contains\n        -> item as String\n        <- rtn as Boolean: items contains item\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07500"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07500/good.ek9","url":"https://ek9.io/errors/E07500.html","title":"Mark it 'as pure'","code":"#!ek9\ndefines module error.e07500.good\n\n  defines class\n\n    Basket\n      items <- [\"apple\", \"pear\"]\n\n      operator contains as pure\n        -> item as String\n        <- rtn as Boolean: items contains item\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07500"}
{"id":"errors/E07510/bad.ek9","url":"https://ek9.io/errors/E07510.html","title":"E07510: operator must not be declared pure","code":"#!ek9\ndefines module error.e07510.bad\n\n  defines class\n\n    Wallet\n      amount <- 0.0\n\n      holding() as pure\n        <- rtn as Float: amount\n\n      //Copy changes this object, so it cannot be pure\n      operator :=: as pure\n        -> other as Wallet\n        amount :=: other.holding()\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07510"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07510/good.ek9","url":"https://ek9.io/errors/E07510.html","title":"Remove 'as pure' from a mutating operator","code":"#!ek9\ndefines module error.e07510.good\n\n  defines class\n\n    Wallet\n      amount <- 0.0\n\n      holding() as pure\n        <- rtn as Float: amount\n\n      operator :=:\n        -> other as Wallet\n        amount :=: other.holding()\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07510"}
{"id":"errors/E07520/bad.ek9","url":"https://ek9.io/errors/E07520.html","title":"E07520: must return a Boolean","code":"#!ek9\ndefines module error.e07520.bad\n\n  defines class\n\n    Reading\n      celsius <- 0.0\n\n      //'?' answers yes or no\n      override operator ? as pure\n        <- rtn as Integer: 1","expectedOutput":null,"kind":"bad","errors":["E07520"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07520/good.ek9","url":"https://ek9.io/errors/E07520.html","title":"Return a Boolean","code":"#!ek9\ndefines module error.e07520.good\n\n  defines class\n\n    Reading\n      celsius <- 0.0\n\n      override operator ? as pure\n        <- rtn as Boolean: celsius?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07520"}
{"id":"errors/E07530/bad.ek9","url":"https://ek9.io/errors/E07530.html","title":"E07530: only compatible with Boolean type","code":"#!ek9\ndefines module error.e07530.bad\n\n  defines function\n\n    checkCount()\n      -> count as Integer\n\n      //require needs a Boolean\n      require count","expectedOutput":null,"kind":"bad","errors":["E07530"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07530/good.ek9","url":"https://ek9.io/errors/E07530.html","title":"Require a Boolean, such as a set-check","code":"#!ek9\ndefines module error.e07530.good\n\n  defines function\n\n    checkCount()\n      -> count as Integer\n\n      //'?' gives a Boolean: is count set?\n      require count?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07530"}
{"id":"errors/E07540/bad.ek9","url":"https://ek9.io/errors/E07540.html","title":"E07540: is not compatible with a Boolean type","code":"#!ek9\ndefines module error.e07540.bad\n\n  defines function\n\n    choose()\n      -> label as String\n      <- rtn as String: String()\n\n      //The control of a ternary must be a Boolean\n      rtn: label <- \"A\" else \"B\"","expectedOutput":null,"kind":"bad","errors":["E07540"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07540/good.ek9","url":"https://ek9.io/errors/E07540.html","title":"Use a Boolean control","code":"#!ek9\ndefines module error.e07540.good\n\n  defines function\n\n    choose()\n      -> useFirst as Boolean\n      <- rtn as String: useFirst <- \"A\" else \"B\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07540"}
{"id":"errors/E07550/bad.ek9","url":"https://ek9.io/errors/E07550.html","title":"E07550: must return an Integer","code":"#!ek9\ndefines module error.e07550.bad\n\n  defines class\n\n    Score\n\n      //'<=>' answers less, equal or greater as an Integer\n      operator <=> as pure\n        -> other as Score\n        <- rtn as Score: this","expectedOutput":null,"kind":"bad","errors":["E07550"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07550/good.ek9","url":"https://ek9.io/errors/E07550.html","title":"Return an Integer","code":"#!ek9\ndefines module error.e07550.good\n\n  defines class\n\n    Score\n      points as Integer?\n\n      default private Score()\n\n      Score()\n        -> initial as Integer\n        this.points: initial\n\n      total() as pure\n        <- rtn as Integer: points\n\n      //Negative, zero or positive\n      operator <=> as pure\n        -> other as Score\n        <- rtn as Integer: points <=> other.total()\n\n      operator #? as pure\n        <- rtn as Integer: #?points\n\n      override operator ? as pure\n        <- rtn as Boolean: points?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07550"}
{"id":"errors/E07560/bad.ek9","url":"https://ek9.io/errors/E07560.html","title":"E07560: must be an Integer with a value greater than zero","code":"#!ek9\ndefines module error.e07560.bad\n\n  defines function\n\n    firstOnes()\n      <- rtn as List of String: List()\n\n      //head of nothing makes no sense\n      cat [\"last\", \"first\"] | head 0 > rtn","expectedOutput":null,"kind":"bad","errors":["E07560"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07560/good.ek9","url":"https://ek9.io/errors/E07560.html","title":"Use a count of one or more","code":"#!ek9\ndefines module error.e07560.good\n\n  defines function\n\n    firstOnes()\n      <- rtn as List of String: List()\n      cat [\"last\", \"first\"] | head 1 > rtn","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07560"}
{"id":"errors/E07570/bad.ek9","url":"https://ek9.io/errors/E07570.html","title":"E07570: must return a String","code":"#!ek9\ndefines module error.e07570.bad\n\n  defines class\n\n    Label\n      text <- \"label\"\n\n      //'$' converts to a String\n      operator $ as pure\n        <- rtn as Integer: length text\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07570"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07570/good.ek9","url":"https://ek9.io/errors/E07570.html","title":"Return a String","code":"#!ek9\ndefines module error.e07570.good\n\n  defines class\n\n    Label\n      text <- \"label\"\n\n      operator $ as pure\n        <- rtn as String: text\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07570"}
{"id":"errors/E07580/bad.ek9","url":"https://ek9.io/errors/E07580.html","title":"E07580: must return a JSON","code":"#!ek9\ndefines module error.e07580.bad\n\n  defines class\n\n    Label\n      text <- \"label\"\n\n      //'$$' converts to JSON\n      operator $$ as pure\n        <- rtn as String: text\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07580"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07580/good.ek9","url":"https://ek9.io/errors/E07580.html","title":"Return JSON","code":"#!ek9\ndefines module error.e07580.good\n\n  defines class\n\n    Label\n      text <- \"label\"\n\n      operator $$ as pure\n        <- rtn as JSON: JSON(\"text\", JSON(text))\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07580"}
{"id":"errors/E07590/bad.ek9","url":"https://ek9.io/errors/E07590.html","title":"E07590: if a program returns a value it can only be an Integer","code":"#!ek9\ndefines module error.e07590.bad\n\n  defines record\n    ATestRecord\n      first <- \"A\"\n      second <- 9\n\n  defines program\n\n    //Failure 1 - cannot return anything other than an Integer\n    BadReturnType1()\n      <- rtn as Float: 0.9\n      //Just some body to stop any other compiler errors\n      v <- \"Steve\"\n      require v?\n\n    //Failure 2 - but mainValue not set on\n    BadReturnType2()\n      <- rtn as Float?\n      rtn: 5.6\n\n    //Failure 3 - simple type inference - but still not allowed type\n    BadReturnType3()\n      <- rtn <- false\n      //Just some body to stop any other compiler errors\n      v <- \"Steve\"\n      require v?\n\n    //Failure 4 - a specific developer created type\n    BadReturnType4()\n      <- rtn as ATestRecord?\n      //Just some body to stop any other compiler errors\n      v <- \"Steve\"\n      require v?\n\n    //Failure 5 - a record declared LATER in the file; not resolvable in SYMBOL_DEFINITION (front-end audit FE37)\n    BadReturnType5()\n      <- rtn as LaterRecord?\n      //Just some body to stop any other compiler errors\n      v <- \"Steve\"\n      require v?\n\n    ValidProgramNoReturn()\n      v <- \"Steve\"\n      require v?\n\n    ValidProgramIntegerReturn1()\n      <- rtn as Integer: 0\n      //Just some body to stop any other compiler errors\n      v <- \"Steve\"\n      require v?\n\n    //Valid with type inference and shorthand return notation.\n    ValidProgramIntegerReturn2()\n      <- rtn <- 0\n      //Just some body to stop any other compiler errors\n      v <- \"Steve\"\n      require v?\n\n    //Valid - an Integer inferred from a constructor call. Rejected with a false E07590 while this check ran in\n    //SYMBOL_DEFINITION, where an inferred returning param has no type yet (front-end audit FE37).\n    ValidProgramIntegerReturn3()\n      <- rtn <- Integer(3)\n      //Just some body to stop any other compiler errors\n      v <- \"Steve\"\n      require v?\n\n  defines function\n\n    validIntegerReturn()\n      <- rtn <- 1\n\n    validFloatReturn()\n      <- rtn <- 4.56\n\n    validTimeReturn()\n      <- rtn <- 12:23:15\n\n    validDateReturn()\n      <- rtn <- 2023-02-24\n\n    validDateTimeReturn()\n      <- rtn <- 2023-02-24T15:48:21Z\n\n    //Two weeks\n    validDurationReturn()\n      <- rtn <- P2W\n\n    validMillisecondReturn()\n      <- rtn <- 202ms\n\n    validBitsReturn()\n      <- rtn <- 0b010110\n\n    validMoneyReturn()\n      <- rtn <- 330.26#GBP\n\n    validColourReturn()\n      <- rtn <- #CC04FADD\n\n    validDimensionReturn()\n      <- rtn <- 23.5km\n\n    validPathReturn()\n      <- rtn <- $?.some.path.inc[0].array\n\n    validRegexReturn()\n      <- rtn <- /[a-zA-Z0-9]{6}/\n\n  defines record\n    LaterRecord\n      name <- \"later\"","expectedOutput":null,"kind":"bad","errors":["E07590"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07590/good.ek9","url":"https://ek9.io/errors/E07590.html","title":"Return an Integer exit code, or nothing","code":"#!ek9\ndefines module error.e07590.good\n\n  defines program\n\n    //The only value a program can return is its Integer exit code\n    Check()\n      <- rtn as Integer: 0\n      stdout <- Stdout()\n      stdout.println(\"checked\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07590"}
{"id":"errors/E07600/bad.ek9","url":"https://ek9.io/errors/E07600.html","title":"E07600: program arguments are limited to a finite range of EK9 built in types","code":"#!ek9\ndefines module error.e07600.bad\n\n  defines record\n\n    Person\n      name <- String()\n      age <- Integer()\n\n      default operator ?\n\n  defines program\n\n    //The command line holds text, which EK9 converts to its built-in types only\n    Register()\n      -> person as Person\n      stdout <- Stdout()\n      stdout.println(\"registered\")","expectedOutput":null,"kind":"bad","errors":["E07600"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07600/good.ek9","url":"https://ek9.io/errors/E07600.html","title":"Take built-in types and build the record","code":"#!ek9\ndefines module error.e07600.good\n\n  defines record\n\n    Person\n      name <- String()\n      age <- Integer()\n\n      Person()\n        ->\n          personName as String\n          personAge as Integer\n        this.name :=: personName\n        this.age :=: personAge\n\n      default operator ?\n\n  defines program\n\n    //Take built-in types, and build the record from them\n    Register()\n      ->\n        name as String\n        age as Integer\n      stdout <- Stdout()\n      person <- Person(name, age)\n      stdout.println(`registered: ${person.name}`)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07600"}
{"id":"errors/E07610/bad.ek9","url":"https://ek9.io/errors/E07610.html","title":"E07610: inappropriate combination of program arguments","code":"#!ek9\ndefines module error.e07610.bad\n\n  defines program\n\n    //Either name every argument, or take them all as a List of String\n    Serve()\n      ->\n        port as Integer\n        commandLine as List of String\n      stdout <- Stdout()\n      stdout.println(`serving on ${port}`)","expectedOutput":null,"kind":"bad","errors":["E07610"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07610/good.ek9","url":"https://ek9.io/errors/E07610.html","title":"Name every argument, or take them all as a List of String","code":"#!ek9\ndefines module error.e07610.good\n\n  defines program\n\n    //Option 1: name every argument\n    Serve()\n      ->\n        port as Integer\n        host as String\n      stdout <- Stdout()\n      stdout.println(`serving ${host} on ${port}`)\n\n    //Option 2: take them all, and read them yourself\n    ServeRaw()\n      -> commandLine as List of String\n      stdout <- Stdout()\n      stdout.println(`${length commandLine} arguments`)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07610"}
{"id":"errors/E07620/bad.ek9","url":"https://ek9.io/errors/E07620.html","title":"E07620: operator not defined","code":"#!ek9\ndefines module error.e07620.bad\n\n  defines function\n    someCall()\n      <- rtn <- 32\n\n    someCallWrongType()\n      <- rtn <- true\n\n  defines program\n\n    ASimpleSwitch()\n      stdout <- Stdout()\n      multiplier <- 5\n      anotherMultiplier <- 8.33\n\n      //This is what we will use to 'switch on'\n      conditionVariable <- 21\n\n      //This is what we will vary based on the condition variable\n      resultText <- String()\n\n      switch conditionVariable\n        case \"wrongType\"\n          resultText: \"Should be Compiler error\"\n        case matches 100\n          resultText: \"Also should be Compiler error\"\n        case == 10.0\n          resultText: \"Again should be Compiler error\"\n        case <> 2009-12-01\n          resultText: \"A Date - another Compiler error\"\n        case <> 32ms, matches 25\n          resultText: \"Errors here, just show first Compiler error\"\n        case == 10*anotherMultiplier\n          resultText: \"Errors here, due to a Float\"\n        case == anotherMultiplier*78\n          resultText: \"Errors here, due to a Float\"\n        case someCallWrongType()\n          resultText: \"Errors here, due to a Boolean return\"\n        case < 12\n          resultText: \"Moderate\"\n        case > 10*multiplier\n          resultText: \"Very High\"\n        case 25, 26, 27\n          resultText: \"Slightly High\"\n        case 21, 22, 23, 24\n          resultText: \"Perfect\"\n        case someCall()\n          resultText: \"From A Call\"\n        default\n          resultText: \"Not Suitable\"\n\n      stdout.println(resultText)","expectedOutput":null,"kind":"bad","errors":["E07620"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07620/good.ek9","url":"https://ek9.io/errors/E07620.html","title":"Compare the subject with values of its own type","code":"#!ek9\ndefines module error.e07620.good\n\n  defines function\n\n    rate()\n      -> conditionVariable as Integer\n      <- rtn as String: String()\n\n      //Every case compares an Integer with an Integer\n      resultText <- switch conditionVariable\n        <- text as String: String()\n        case < 12\n          text: \"Moderate\"\n        case 25, 26, 27\n          text: \"Slightly High\"\n        case 21, 22, 23, 24\n          text: \"Perfect\"\n        default\n          text: \"Not Suitable\"\n\n      rtn: resultText","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07620"}
{"id":"errors/E07630/bad.ek9","url":"https://ek9.io/errors/E07630.html","title":"E07630: operator cannot be used on an Enumeration in this way","code":"#!ek9\ndefines module error.e07630.bad\n\n  defines type\n\n    CardSuit\n      Hearts\n      Diamonds\n      Clubs\n      Spades\n\n  defines function\n\n    describeSuits()\n      stdout <- Stdout()\n\n      //CardSuit is the type; '$' applies to one of its values\n      stdout.println($CardSuit)","expectedOutput":null,"kind":"bad","errors":["E07630"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07630/good.ek9","url":"https://ek9.io/errors/E07630.html","title":"Apply the operator to a value of the enumeration","code":"#!ek9\ndefines module error.e07630.good\n\n  defines type\n\n    CardSuit\n      Hearts\n      Diamonds\n      Clubs\n      Spades\n\n  defines program\n\n    DescribeSuits()\n      stdout <- Stdout()\n\n      //Every value of the enumeration, in order\n      for suit in CardSuit\n        stdout.println($suit)\n\n      //Operators apply to values, and the values are ordered\n      hearts <- CardSuit.Hearts\n      stdout.println($hearts)\n      stdout.println($(hearts < CardSuit.Spades))","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07630"}
{"id":"errors/E07640/bad.ek9","url":"https://ek9.io/errors/E07640.html","title":"E07640: use <> for the not equal operator","code":"#!ek9\ndefines module error.e07640.bad\n\n  defines class\n\n    Point\n\n      //'<>' is EK9's not-equal\n      operator != as pure\n        -> other as Point\n        <- rtn as Boolean: true","expectedOutput":null,"kind":"bad","errors":["E07640"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07640/good.ek9","url":"https://ek9.io/errors/E07640.html","title":"Use '<>', generated from the type's sameness","code":"#!ek9\ndefines module error.e07640.good\n\n  defines class\n\n    Point\n      x <- 0\n      y <- 0\n\n      default private Point()\n\n      Point()\n        ->\n          across as Integer\n          down as Integer\n        this.x: across\n        this.y: down\n\n      //Equatable sameness: '<>' is generated from '=='\n      default operator ==\n      default operator #?\n      default operator ?\n\n  defines program\n\n    ComparePoints()\n      stdout <- Stdout()\n      first <- Point(1, 2)\n      second <- Point(2, 1)\n      if first <> second\n        stdout.println(\"different points\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07640"}
{"id":"errors/E07650/bad.ek9","url":"https://ek9.io/errors/E07650.html","title":"E07650: use ~ for the not operator","code":"#!ek9\ndefines module error.e07650.bad\n\n  defines class\n\n    Toggle\n      on <- false\n\n      //Negation is the '~' operator\n      operator not as pure\n        <- rtn as Toggle: this\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07650"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07650/good.ek9","url":"https://ek9.io/errors/E07650.html","title":"Declare negation as '~'","code":"#!ek9\ndefines module error.e07650.good\n\n  defines class\n\n    Toggle\n      on as Boolean?\n\n      default private Toggle() as pure\n\n      Toggle() as pure\n        -> initial as Boolean\n        this.on :=? initial\n\n      operator ~ as pure\n        <- rtn as Toggle: Toggle(not on)\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07650"}
{"id":"errors/E07660/bad.ek9","url":"https://ek9.io/errors/E07660.html","title":"E07660: operator name cannot be used as a method","code":"#!ek9\ndefines module error.e07660.bad\n\n  defines text for \"en\"\n\n    ButtonLabels\n      close()\n        \"Close\"\n\n      length()\n        \"Length\"\n\n      contains()\n        -> item as String\n        `Contains ${item}`\n\n      openLabel()\n        \"Open\"","expectedOutput":null,"kind":"bad","errors":["E07660"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07660/good.ek9","url":"https://ek9.io/errors/E07660.html","title":"Name the method for what it gives","code":"#!ek9\ndefines module error.e07660.good\n\n  defines text for \"en\"\n\n    ButtonLabels\n      closeLabel()\n        \"Close\"\n\n      lengthLabel()\n        \"Length\"\n\n      containsLabel()\n        -> item as String\n        `Contains ${item}`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07660"}
{"id":"errors/E07670/bad.ek9","url":"https://ek9.io/errors/E07670.html","title":"E07670: operator not supported, only +=, -=, :^:, :~: and ? are supported","code":"#!ek9\ndefines module error.e07670.bad\n\n  defines service\n\n    Addresses for :/addresses open\n\n      //Only +=, -=, :^:, :~: and ? map to HTTP verbs\n      operator <~> for :/\n        -> incoming as String :=: CONTENT\n        <- response as HTTPResponse: TextResponse(incoming)\n\n      //One form each: a service adds with '+=' (POST), never '+'\n      operator + for :/add  //wrong: write '+='\n        -> incoming as String :=: CONTENT\n        <- response as HTTPResponse: TextResponse(incoming)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07670"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07670/good.ek9","url":"https://ek9.io/errors/E07670.html","title":"Use an operator that maps to an HTTP verb, or a named method","code":"#!ek9\ndefines module error.e07670.good\n\n  defines service\n\n    Addresses for :/addresses open\n\n      //'+=' is POST\n      operator += for :/\n        -> incoming as String :=: CONTENT\n        <- response as HTTPResponse: TextResponse(incoming)\n\n      //Or a named method with its verb\n      byId() as GET for :/{id}\n        -> id as String\n        <- response as HTTPResponse: TextResponse(`address ${id}`)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07670"}
{"id":"errors/E07671/bad.ek9","url":"https://ek9.io/errors/E07671.html","title":"E07671: a service URI needs 'for' before it and an HTTP verb needs 'as' before it","code":"#!ek9\ndefines module error.e07671.bad\n\n  defines service\n\n    //A URI is written after 'for'\n    Addresses :/addresses open  //wrong: no 'for' before the URI\n\n      //An HTTP verb is written after 'as'\n      byId() GET for :/{id}  //wrong: no 'as' before the verb\n        -> id as String\n        <- response as HTTPResponse: TextResponse(`address ${id}`)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07671"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07671/good.ek9","url":"https://ek9.io/errors/E07671.html","title":"Write 'for' before every URI and 'as' before the HTTP verb","code":"#!ek9\ndefines module error.e07671.good\n\n  defines service\n\n    Addresses for :/addresses open\n\n      byId() as GET for :/{id}\n        -> id as String\n        <- response as HTTPResponse: TextResponse(`address ${id}`)\n\n      operator += for :/\n        -> incoming as String :=: CONTENT\n        <- response as HTTPResponse: TextResponse(incoming)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07671"}
{"id":"errors/E07680/bad.ek9","url":"https://ek9.io/errors/E07680.html","title":"E07680: URI with place holder variable not supported in this context","code":"#!ek9\ndefines module error.e07680.bad\n\n  defines service\n\n    //The service's own URI is fixed\n    Addresses for :/addresses/{region} open\n\n      byId() as GET for :/{id}\n        -> id as String\n        <- response as HTTPResponse: TextResponse(`address ${id}`)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07680"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07680/good.ek9","url":"https://ek9.io/errors/E07680.html","title":"Keep the service URI fixed; put variables in the methods","code":"#!ek9\ndefines module error.e07680.good\n\n  defines service\n\n    Addresses for :/addresses open\n\n      //Variables go in the method's URI\n      byRegion() as GET for :/{region}/{id}\n        ->\n          region as String\n          id as String\n        <- response as HTTPResponse: TextResponse(`${region} ${id}`)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07680"}
{"id":"errors/E07690/bad.ek9","url":"https://ek9.io/errors/E07690.html","title":"E07690: HTTP access verb not supported in this context","code":"#!ek9\ndefines module error.e07690.bad\n\n  defines service\n\n    Addresses for :/addresses open\n\n      create() as POST for :/\n        -> incoming as String :=: CONTENT\n        <- response as HTTPResponse: TextResponse(normalise(incoming))\n\n      //Not an HTTP method, so there is no request to take CONTENT from\n      private normalise()\n        -> text as String :=: CONTENT\n        <- rtn as String: text.trim()\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07690"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07690/good.ek9","url":"https://ek9.io/errors/E07690.html","title":"Bind HTTP values only on the HTTP method","code":"#!ek9\ndefines module error.e07690.good\n\n  defines service\n\n    Addresses for :/addresses open\n\n      //The HTTP method takes the CONTENT...\n      create() as POST for :/\n        -> incoming as String :=: CONTENT\n        <- response as HTTPResponse: TextResponse(normalise(incoming))\n\n      //...and passes it to a helper with an ordinary parameter\n      private normalise()\n        -> text as String\n        <- rtn as String: text.trim()\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07690"}
{"id":"errors/E07700/bad.ek9","url":"https://ek9.io/errors/E07700.html","title":"E07700: HTTP PATH parameter is invalid","code":"#!ek9\ndefines module error.e07700.bad\n\n  defines service\n\n    Addresses for :/addresses open\n\n      byId() as GET for :/{address-id}\n        ->\n          //There is no {no-such-path} in the URI\n          addressId as Integer :=: PATH \"no-such-path\"\n        <- response as HTTPResponse: TextResponse(`address ${addressId}`)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07700"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07700/good.ek9","url":"https://ek9.io/errors/E07700.html","title":"Name the URI's variable","code":"#!ek9\ndefines module error.e07700.good\n\n  defines service\n\n    Addresses for :/addresses open\n\n      //Name the URI variable exactly\n      byId() as GET for :/{address-id}\n        -> addressId as Integer :=: PATH \"address-id\"\n        <- response as HTTPResponse: TextResponse(`address ${addressId}`)\n\n      //Or name the parameter as the variable, and PATH is implied\n      byRoute() as GET for :/route/{routeId}\n        -> routeId as String\n        <- response as HTTPResponse: TextResponse(`route ${routeId}`)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07700"}
{"id":"errors/E07710/bad.ek9","url":"https://ek9.io/errors/E07710.html","title":"E07710: additional name needed for QUERY, HEADER or PATH parameters","code":"#!ek9\ndefines module error.e07710.bad\n\n  defines service\n\n    Addresses for :/addresses open\n\n      byAgent() as GET for :/agent\n        ->\n          //Which header?\n          agent as String :=: HEADER\n        <- response as HTTPResponse: TextResponse(agent)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07710"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07710/good.ek9","url":"https://ek9.io/errors/E07710.html","title":"Name the header, query or path value","code":"#!ek9\ndefines module error.e07710.good\n\n  defines service\n\n    Addresses for :/addresses open\n\n      byAgent() as GET for :/agent\n        -> agent as String :=: HEADER \"User-Agent\"\n        <- response as HTTPResponse: TextResponse(agent)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07710"}
{"id":"errors/E07720/bad.ek9","url":"https://ek9.io/errors/E07720.html","title":"E07720: additional name only required for QUERY, HEADER or PATH parameters","code":"#!ek9\ndefines module error.e07720.bad\n\n  defines service\n\n    Addresses for :/addresses open\n\n      whole() as POST for :/\n        ->\n          //The whole request has no name\n          request as HTTPRequest :=: REQUEST \"body\"\n        <- response as HTTPResponse: TextResponse($request)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07720"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07720/good.ek9","url":"https://ek9.io/errors/E07720.html","title":"Remove the name from REQUEST, CONTENT and CONTEXT","code":"#!ek9\ndefines module error.e07720.good\n\n  defines service\n\n    Addresses for :/addresses open\n\n      whole() as POST for :/\n        -> request as HTTPRequest :=: REQUEST\n        <- response as HTTPResponse: TextResponse($request)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07720"}
{"id":"errors/E07730/bad.ek9","url":"https://ek9.io/errors/E07730.html","title":"E07730: HTTP PATH variable count and PATH parameter count mismatch","code":"#!ek9\ndefines module error.e07730.bad\n\n  defines service\n\n    Addresses for :/addresses open\n\n      //Two variables in the URI, one parameter\n      byRoute() as GET for :/{region}/{route}\n        -> region as String\n        <- response as HTTPResponse: TextResponse(region)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07730"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07730/good.ek9","url":"https://ek9.io/errors/E07730.html","title":"Declare a parameter for every URI variable","code":"#!ek9\ndefines module error.e07730.good\n\n  defines service\n\n    Addresses for :/addresses open\n\n      byRoute() as GET for :/{region}/{route}\n        ->\n          region as String\n          route as String\n        <- response as HTTPResponse: TextResponse(`${region} ${route}`)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07730"}
{"id":"errors/E07731/bad.ek9","url":"https://ek9.io/errors/E07731.html","title":"E07731: each HTTP PATH variable must be bound by exactly one PATH parameter","code":"#!ek9\ndefines module error.e07731.bad\n\n  defines service\n\n    Items for :/items open\n\n      //Valid control: each placeholder bound once.\n      pair() for :/{a}/{b}/pair.html\n        ->\n          first as String :=: PATH \"a\"\n          second as String :=: PATH \"b\"\n        <-\n          response as HTTPResponse: () with trait of HTTPResponse\n\n      //Both explicit parameters bind {a}; {b} is never bound.\n      twiceExplicit() for :/{a}/{b}/twiceExplicit.html\n        ->\n          first as String :=: PATH \"a\"\n          second as String :=: PATH \"a\"\n        <-\n          response as HTTPResponse: () with trait of HTTPResponse\n\n      //'a' is an inferred PATH \"a\" binding, and the explicit parameter binds {a} again; {b} unbound.\n      twiceInferred() for :/{a}/{b}/twiceInferred.html\n        ->\n          a as String\n          other as String :=: PATH \"a\"\n        <-\n          response as HTTPResponse: () with trait of HTTPResponse\n\n      //The same placeholder twice in one URI has no single meaning, so it is rejected outright.\n      repeated() for :/{a}/{a}/repeated.html\n        ->\n          first as String :=: PATH \"a\"\n          second as String :=: PATH \"a\"\n        <-\n          response as HTTPResponse: () with trait of HTTPResponse","expectedOutput":null,"kind":"bad","errors":["E07731"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07731/good.ek9","url":"https://ek9.io/errors/E07731.html","title":"Bind each path variable once","code":"#!ek9\ndefines module error.e07731.good\n\n  defines service\n\n    Items for :/items open\n\n      //Each variable bound exactly once\n      pair() as GET for :/{a}/{b}/pair.html\n        ->\n          first as String :=: PATH \"a\"\n          second as String :=: PATH \"b\"\n        <- response as HTTPResponse: TextResponse(`${first} ${second}`)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07731"}
{"id":"errors/E07740/bad.ek9","url":"https://ek9.io/errors/E07740.html","title":"E07740: implementation not provided, but services cannot be abstract","code":"#!ek9\ndefines module error.e07740.bad\n\n  defines service\n\n    Addresses for :/addresses open\n\n      //A service is never abstract: every method has a body\n      byId() as GET for :/{id}\n        -> id as String\n        <- response as HTTPResponse?\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07740"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07740/good.ek9","url":"https://ek9.io/errors/E07740.html","title":"Give the service method a body","code":"#!ek9\ndefines module error.e07740.good\n\n  defines service\n\n    Addresses for :/addresses open\n\n      byId() as GET for :/{id}\n        -> id as String\n        <- response as HTTPResponse: TextResponse(`address ${id}`)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07740"}
{"id":"errors/E07750/bad.ek9","url":"https://ek9.io/errors/E07750.html","title":"E07750: Web Service return type must be compatible with HTTPResponse","code":"#!ek9\ndefines module error.e07750.bad\n\n  defines service\n\n    Numbers for :/numbers open\n\n      //A service method answers with an HTTPResponse\n      count() as GET for :/count\n        <- total as Integer: 42\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07750"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07750/good.ek9","url":"https://ek9.io/errors/E07750.html","title":"Return an HTTPResponse carrying the value","code":"#!ek9\ndefines module error.e07750.good\n\n  defines service\n\n    Numbers for :/numbers open\n\n      count() as GET for :/count\n        <- response as HTTPResponse: TextResponse($42)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07750"}
{"id":"errors/E07760/bad.ek9","url":"https://ek9.io/errors/E07760.html","title":"E07760: only Integer, String, Date, Time, DateTime, Milliseconds, Duration, HTTPRequest and HTTPContext supported","code":"#!ek9\ndefines module error.e07760.bad\n\n  defines service\n\n    Addresses for :/addresses open\n\n      byAmount() as GET for :/amount\n        ->\n          //A Float cannot be bound from a URI\n          amount as Float :=: QUERY \"amount\"\n        <- response as HTTPResponse: TextResponse($amount)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07760"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07760/good.ek9","url":"https://ek9.io/errors/E07760.html","title":"Use a type that can be bound","code":"#!ek9\ndefines module error.e07760.good\n\n  defines service\n\n    Addresses for :/addresses open\n\n      //Integer, String, Date, Time, DateTime, Milliseconds and Duration can be bound\n      search() as GET for :/{index-number}/search\n        ->\n          queryId as Integer :=: PATH \"index-number\"\n          fromDate as Date :=: QUERY \"from\"\n          span as Duration :=: QUERY \"duration\"\n          timeOut as Millisecond :=: QUERY \"time-out\"\n        <- response as HTTPResponse: TextResponse(`${queryId} ${fromDate} ${span} ${timeOut}`)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07760"}
{"id":"errors/E07770/bad.ek9","url":"https://ek9.io/errors/E07770.html","title":"E07770: Web Service parameter type must be HTTPRequest for REQUEST","code":"#!ek9\ndefines module error.e07770.bad\n\n  defines service\n\n    Addresses for :/addresses open\n\n      whole() as POST for :/\n        ->\n          //The whole request is an HTTPRequest\n          request as String :=: REQUEST\n        <- response as HTTPResponse: TextResponse(request)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07770"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07770/good.ek9","url":"https://ek9.io/errors/E07770.html","title":"Take REQUEST as an HTTPRequest","code":"#!ek9\ndefines module error.e07770.good\n\n  defines service\n\n    Addresses for :/addresses open\n\n      whole() as POST for :/\n        -> request as HTTPRequest :=: REQUEST\n        <- response as HTTPResponse: TextResponse($request)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07770"}
{"id":"errors/E07780/bad.ek9","url":"https://ek9.io/errors/E07780.html","title":"E07780: Web Service type HTTPRequest can only be used by itself","code":"#!ek9\ndefines module error.e07780.bad\n\n  defines service\n\n    Addresses for :/addresses open\n\n      whole() as POST for :/\n        ->\n          //The whole request already holds every query value\n          request as HTTPRequest :=: REQUEST\n          count as Integer :=: QUERY \"count\"\n        <- response as HTTPResponse: TextResponse(`${request} ${count}`)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07780"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07780/good.ek9","url":"https://ek9.io/errors/E07780.html","title":"Take the whole request alone, or the individual values","code":"#!ek9\ndefines module error.e07780.good\n\n  defines service\n\n    Addresses for :/addresses open\n\n      //Either the whole request, alone...\n      whole() as POST for :/\n        -> request as HTTPRequest :=: REQUEST\n        <- response as HTTPResponse: TextResponse($request)\n\n      //...or the individual values\n      parts() as POST for :/parts\n        ->\n          count as Integer :=: QUERY \"count\"\n          incoming as String :=: CONTENT\n        <- response as HTTPResponse: TextResponse(`${count} ${incoming}`)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07780"}
{"id":"errors/E07790/bad.ek9","url":"https://ek9.io/errors/E07790.html","title":"E07790: Web Service parameter type cannot be HTTPRequest","code":"#!ek9\ndefines module error.e07790.bad\n\n  defines service\n\n    Addresses for :/addresses open\n\n      search() as GET for :/search\n        ->\n          //A query value is text, never the whole request\n          request as HTTPRequest :=: QUERY \"q\"\n        <- response as HTTPResponse: TextResponse($request)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07790"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07790/good.ek9","url":"https://ek9.io/errors/E07790.html","title":"Use HTTPRequest only with REQUEST","code":"#!ek9\ndefines module error.e07790.good\n\n  defines service\n\n    Addresses for :/addresses open\n\n      search() as GET for :/search\n        -> term as String :=: QUERY \"q\"\n        <- response as HTTPResponse: TextResponse(term)\n\n      whole() as POST for :/\n        -> request as HTTPRequest :=: REQUEST\n        <- response as HTTPResponse: TextResponse($request)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07790"}
{"id":"errors/E07791/bad.ek9","url":"https://ek9.io/errors/E07791.html","title":"E07791: Web Service parameter type must be HTTPContext for CONTEXT","code":"#!ek9\ndefines module error.e07791.bad\n\n  defines service\n\n    Addresses for :/addresses open\n\n      info() as GET for :/info\n        ->\n          //CONTEXT is an HTTPContext\n          context as String :=: CONTEXT\n        <- response as HTTPResponse: TextResponse(context)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07791"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07791/good.ek9","url":"https://ek9.io/errors/E07791.html","title":"Take CONTEXT as an HTTPContext","code":"#!ek9\ndefines module error.e07791.good\n\n  defines service\n\n    Addresses for :/addresses open\n\n      info() as GET for :/info\n        -> context as HTTPContext :=: CONTEXT\n        <- response as HTTPResponse: TextResponse($context)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07791"}
{"id":"errors/E07792/bad.ek9","url":"https://ek9.io/errors/E07792.html","title":"E07792: Web Service type HTTPContext can only be used by itself","code":"#!ek9\ndefines module error.e07792.bad\n\n  defines service\n\n    Addresses for :/addresses open\n\n      info() as GET for :/info\n        ->\n          //The context already holds every query value\n          context as HTTPContext :=: CONTEXT\n          filter as String :=: QUERY \"q\"\n        <- response as HTTPResponse: TextResponse(`${context} ${filter}`)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07792"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07792/good.ek9","url":"https://ek9.io/errors/E07792.html","title":"Take the context alone","code":"#!ek9\ndefines module error.e07792.good\n\n  defines service\n\n    Addresses for :/addresses open\n\n      info() as GET for :/info\n        -> context as HTTPContext :=: CONTEXT\n        <- response as HTTPResponse: TextResponse($context)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07792"}
{"id":"errors/E07793/bad.ek9","url":"https://ek9.io/errors/E07793.html","title":"E07793: Web Service parameter type cannot be HTTPContext","code":"#!ek9\ndefines module error.e07793.bad\n\n  defines service\n\n    Addresses for :/addresses open\n\n      info() as GET for :/info\n        ->\n          //A query value is text, never the context\n          context as HTTPContext :=: QUERY \"q\"\n        <- response as HTTPResponse: TextResponse($context)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07793"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07793/good.ek9","url":"https://ek9.io/errors/E07793.html","title":"Use HTTPContext only with CONTEXT","code":"#!ek9\ndefines module error.e07793.good\n\n  defines service\n\n    Addresses for :/addresses open\n\n      info() as GET for :/info\n        -> context as HTTPContext :=: CONTEXT\n        <- response as HTTPResponse: TextResponse($context)\n\n      search() as GET for :/search\n        -> term as String :=: QUERY \"q\"\n        <- response as HTTPResponse: TextResponse(term)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07793"}
{"id":"errors/E07800/bad.ek9","url":"https://ek9.io/errors/E07800.html","title":"E07800: Web Service must have return value and it must be compatible with HTTPResponse","code":"#!ek9\ndefines module error.e07800.bad\n\n  defines service\n\n    Addresses for :/addresses open\n\n      //A service method answers every request\n      byId() as GET for :/{id}\n        -> id as String\n        stdout <- Stdout()\n        stdout.println(id)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E07800"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07800/good.ek9","url":"https://ek9.io/errors/E07800.html","title":"Declare the HTTPResponse it returns","code":"#!ek9\ndefines module error.e07800.good\n\n  defines service\n\n    Addresses for :/addresses open\n\n      byId() as GET for :/{id}\n        -> id as String\n        <- response as HTTPResponse: TextResponse(`address ${id}`)\n\n\n  defines class\n\n    TextResponse with trait of HTTPResponse\n      text as String?\n\n      default private TextResponse()\n\n      TextResponse()\n        -> body as String\n        this.text: body\n\n      override content()\n        <- rtn as Bytes: Bytes().withUtf8(text)\n\n      override status() as pure\n        <- rtn as Integer: 200\n\n      override contentType() as pure\n        <- rtn as String: \"text/plain\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07800"}
{"id":"errors/E07810/bad.ek9","url":"https://ek9.io/errors/E07810.html","title":"E07810: Dispatch only supported in classes","code":"#!ek9\ndefines module error.e07810.bad\n\n  defines class\n    Shape as open\n      kind()\n        <- rtn as String: \"shape\"\n\n  defines trait\n\n    Describer\n\n      //Dispatch chooses a method on a class's actual argument types\n      describe() as dispatcher\n        -> shape as Shape\n        <- rtn as String: shape.kind()","expectedOutput":null,"kind":"bad","errors":["E07810"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07810/good.ek9","url":"https://ek9.io/errors/E07810.html","title":"Put the dispatcher on a class","code":"#!ek9\ndefines module error.e07810.good\n\n  defines class\n\n    Shape as open\n      kind()\n        <- rtn as String: \"shape\"\n\n    Circle extends Shape\n      override kind()\n        <- rtn as String: \"circle\"\n\n    Describer\n      describe() as dispatcher\n        -> shape as Shape\n        <- rtn as String: \"some \" + shape.kind()\n\n      describe()\n        -> circle as Circle\n        <- rtn as String: \"a round \" + circle.kind()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07810"}
{"id":"errors/E07820/bad.ek9","url":"https://ek9.io/errors/E07820.html","title":"E07820: only one method can be marked as a dispatcher entry point","code":"#!ek9\ndefines module error.e07820.bad\n\n  defines class\n\n    Shape as open\n      kind()\n        <- rtn as String: \"shape\"\n\n    Circle extends Shape\n      override kind()\n        <- rtn as String: \"circle\"\n\n    Describer\n      describe() as dispatcher\n        -> shape as Shape\n        <- rtn as String: \"some \" + shape.kind()\n\n      //Only the entry point is marked\n      describe() as dispatcher\n        -> circle as Circle\n        <- rtn as String: \"a round \" + circle.kind()","expectedOutput":null,"kind":"bad","errors":["E07820"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07820/good.ek9","url":"https://ek9.io/errors/E07820.html","title":"Mark only the entry point","code":"#!ek9\ndefines module error.e07820.good\n\n  defines class\n\n    Shape as open\n      kind()\n        <- rtn as String: \"shape\"\n\n    Circle extends Shape\n      override kind()\n        <- rtn as String: \"circle\"\n\n    Describer\n      //The one entry point\n      describe() as dispatcher\n        -> shape as Shape\n        <- rtn as String: \"some \" + shape.kind()\n\n      //A handler: not marked\n      describe()\n        -> circle as Circle\n        <- rtn as String: \"a round \" + circle.kind()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07820"}
{"id":"errors/E07830/bad.ek9","url":"https://ek9.io/errors/E07830.html","title":"E07830: unable to find a '|' pipe operator for type","code":"#!ek9\ndefines module error.e07830.bad\n\n  defines class\n\n    DurationCollector\n      total as Duration: Duration()\n\n      operator |\n        -> item as Duration\n        total += item\n\n      default operator ?\n\n  defines function\n\n    collectAll()\n      collector <- DurationCollector()\n\n      //The collector has a '|' for Duration, not for Integer\n      cat [1, 2, 3] > collector","expectedOutput":null,"kind":"bad","errors":["E07830"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07830/good.ek9","url":"https://ek9.io/errors/E07830.html","title":"Pipe in the type the collector's '|' takes","code":"#!ek9\ndefines module error.e07830.good\n\n  defines class\n\n    DurationCollector\n      total as Duration: Duration()\n\n      accumulated() as pure\n        <- rtn as Duration: total\n\n      operator |\n        -> item as Duration\n        total += item\n\n      default operator ?\n\n  defines program\n\n    CollectAll()\n      stdout <- Stdout()\n      collector <- DurationCollector()\n\n      //Duration items into a Duration collector\n      cat [P2D, P1W, PT2H] > collector\n      stdout.println($collector.accumulated())","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07830"}
{"id":"errors/E07835/bad.ek9","url":"https://ek9.io/errors/E07835.html","title":"E07835: 'collect as T' needs T to have a no-argument constructor that can be called where the pipeline is written","code":"#!ek9\ndefines module error.e07835.bad\n\n  defines class\n\n    Tally as open\n      count as Integer?\n\n      default private Tally()\n\n      Tally()\n        -> start as Integer\n        this.count: start\n\n      protected increment()\n        count++\n\n      default operator ?\n\n    //No no-argument constructor: Tally's is private, so none is generated here\n    Counter extends Tally\n      Counter()\n        -> start as Integer\n        super(start)\n\n      operator |\n        -> item as Integer\n        if item?\n          increment()\n\n  defines function\n\n    countAll()\n      <- rtn as Counter?\n\n      //'collect as' makes the Counter with no arguments\n      rtn: for i in 1 ... 3 | collect as Counter","expectedOutput":null,"kind":"bad","errors":["E07835"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07835/good.ek9","url":"https://ek9.io/errors/E07835.html","title":"Give the target type a public no-argument constructor","code":"#!ek9\ndefines module error.e07835.good\n\n  defines record\n\n    Counter\n      count as Integer: Integer()\n\n      operator |\n        -> item as Integer\n        if item?\n          if not count?\n            count: 1\n          else\n            count++\n\n      operator $ as pure\n        <- rtn as String: String()\n        if count?\n          rtn :=? $count\n\n      default operator ?\n\n  defines program\n\n    CountAll()\n      stdout <- Stdout()\n      result <- for i in 1 ... 3 | collect as Counter\n      stdout.println($result)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07835"}
{"id":"errors/E07840/bad.ek9","url":"https://ek9.io/errors/E07840.html","title":"E07840: it does not have compatible iterator() - hasNext()/next() methods","code":"#!ek9\ndefines module error.e07840.bad\n\n  defines class\n\n    Countdown\n      hasNext()\n        <- rtn as Boolean: false\n\n  defines function\n\n    printAll()\n      stdout <- Stdout()\n\n      //A for loop needs next() as well as hasNext()\n      for step in Countdown()\n        stdout.println(\"step\")","expectedOutput":null,"kind":"bad","errors":["E07840"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07840/good.ek9","url":"https://ek9.io/errors/E07840.html","title":"Provide both hasNext() and next()","code":"#!ek9\ndefines module error.e07840.good\n\n  defines class\n\n    Countdown\n      remaining <- 3\n\n      hasNext()\n        <- rtn as Boolean: remaining > 0\n\n      next()\n        <- rtn as Integer: Integer(remaining)\n        remaining--\n\n      default operator ?\n\n  defines program\n\n    PrintAll()\n      stdout <- Stdout()\n\n      //hasNext() and next(): a duck-typed iterator\n      for step in Countdown()\n        stdout.println($step)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07840"}
{"id":"errors/E07845/bad.ek9","url":"https://ek9.io/errors/E07845.html","title":"E07845: a for-range needs an ordered, steppable type - this type has no ordering and no step","code":"#!ek9\ndefines module error.e07845.bad\n\n  defines function\n\n    low() as pure\n      -> text as String\n      <- rtn as String: text\n\n    high() as pure\n      -> text as String\n      <- rtn as String: text\n\n    printSteps()\n      stdout <- Stdout()\n\n      //A function has no order and no next value\n      for step in low ... high\n        stdout.println(\"step\")","expectedOutput":null,"kind":"bad","errors":["E07845"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07845/good.ek9","url":"https://ek9.io/errors/E07845.html","title":"Range over an ordered, steppable type","code":"#!ek9\ndefines module error.e07845.good\n\n  defines program\n\n    PrintSteps()\n      stdout <- Stdout()\n\n      //Integer and Character are ordered and steppable\n      for step in 1 ... 3\n        stdout.println($step)\n\n      for letter in 'a' ... 'c'\n        stdout.println($letter)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07845"}
{"id":"errors/E07845/good_stream.ek9","url":"https://ek9.io/errors/E07845.html","title":"To process several functions, stream a collection of them","code":"#!ek9\ndefines module error.e07845.good.stream\n\n  defines function\n\n    Shout() as abstract\n      -> text as String\n      <- rtn as String?\n\n    loud() is Shout\n      -> text as String\n      <- rtn as String: text.upperCase()\n\n    quiet() is Shout\n      -> text as String\n      <- rtn as String: text.lowerCase()\n\n    applyIt()\n      -> shout as Shout\n      <- rtn as String: shout(\"Hello\")\n\n  defines program\n\n    //To process several functions, stream a collection of them\n    ShoutAll()\n      stdout <- Stdout()\n      handlers as List of Shout: [loud, quiet]\n      cat handlers | map with applyIt > stdout","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07845"}
{"id":"errors/E07845/good_user.ek9","url":"https://ek9.io/errors/E07845.html","title":"Or a type of your own that is ordered and steppable","code":"#!ek9\ndefines module error.e07845.good.user\n\n  defines class\n\n    //Ordered ('<=>'), steppable ('++' and '--'), and copyable (the copy constructor)\n    Step\n      position as Integer?\n\n      default private Step() as pure\n\n      Step() as pure\n        -> initial as Integer\n        position :=? Integer(initial)\n\n      Step() as pure\n        -> other as Step\n        position :=? Integer(other.position)\n\n      operator <=> as pure\n        -> other as Step\n        <- rtn as Integer: position <=> other.position\n\n      operator #? as pure\n        <- rtn as Integer: #?position\n\n      operator $ as pure\n        <- rtn as String: $position\n\n      operator ++\n        position++\n\n      operator --\n        position--\n\n      override operator ? as pure\n        <- rtn as Boolean: position?\n\n  defines program\n\n    PrintSteps()\n      stdout <- Stdout()\n      for step in Step(1) ... Step(3)\n        stdout.println($step)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07845"}
{"id":"errors/E07850/bad.ek9","url":"https://ek9.io/errors/E07850.html","title":"E07850: only a single Exception is supported","code":"#!ek9\ndefines module error.e07850.bad\n\n  defines function\n\n    exceptionFunction()\n      -> count as Integer\n      <- rtn as Integer: count\n      if count < 0\n        throw Exception(\"negative\")\n\n    tryOnce()\n      stdout <- Stdout()\n      try\n        stdout.println($exceptionFunction(-1))\n      catch\n        //A catch takes one exception\n        ->\n          first as Exception\n          second as Exception\n        stdout.println(first.reason() + second.reason())","expectedOutput":null,"kind":"bad","errors":["E07850"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07850/good.ek9","url":"https://ek9.io/errors/E07850.html","title":"Catch a single exception","code":"#!ek9\ndefines module error.e07850.good\n\n  defines function\n\n    exceptionFunction()\n      -> count as Integer\n      <- rtn as Integer: count\n      if count < 0\n        throw Exception(\"negative\")\n\n    tryOnce()\n      stdout <- Stdout()\n      try\n        stdout.println($exceptionFunction(-1))\n      catch\n        -> ex as Exception\n        stdout.println(ex.reason())","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07850"}
{"id":"errors/E07860/bad.ek9","url":"https://ek9.io/errors/E07860.html","title":"E07860: require a function or function delegate","code":"#!ek9\ndefines module error.e07860.bad\n\n  defines function\n\n    doubleAll()\n      <- rtn as List of Integer: List()\n      doubler <- 42\n\n      //map needs a function to apply to each item\n      cat [1, 2, 3] | map with doubler > rtn","expectedOutput":null,"kind":"bad","errors":["E07860"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07860/good.ek9","url":"https://ek9.io/errors/E07860.html","title":"Give map a function","code":"#!ek9\ndefines module error.e07860.good\n\n  defines function\n\n    doubler()\n      -> number as Integer\n      <- rtn as Integer: number * 2\n\n    doubleAll()\n      <- rtn as List of Integer: List()\n      cat [1, 2, 3] | map with doubler > rtn","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07860"}
{"id":"errors/E07870/bad.ek9","url":"https://ek9.io/errors/E07870.html","title":"E07870: require an Integer value or function/function delegate","code":"#!ek9\ndefines module error.e07870.bad\n\n  defines function\n\n    firstOnes()\n      <- rtn as List of String: List()\n      howMany <- \"two\"\n\n      //head takes an Integer, or a function that gives one\n      cat [\"a\", \"b\", \"c\"] | head howMany > rtn","expectedOutput":null,"kind":"bad","errors":["E07870"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07870/good.ek9","url":"https://ek9.io/errors/E07870.html","title":"Give head an Integer, or a function that returns one","code":"#!ek9\ndefines module error.e07870.good\n\n  defines function\n\n    howManyToTake()\n      <- rtn as Integer: 2\n\n    //Option 1: an Integer\n    firstOnes()\n      <- rtn as List of String: List()\n      howMany <- 2\n      cat [\"a\", \"b\", \"c\"] | head howMany > rtn\n\n    //Option 2: a function that gives an Integer\n    firstFew()\n      <- rtn as List of String: List()\n      cat [\"a\", \"b\", \"c\"] | head howManyToTake > rtn","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07870"}
{"id":"errors/E07880/bad.ek9","url":"https://ek9.io/errors/E07880.html","title":"E07880: a function or function delegate is not required here","code":"#!ek9\ndefines module error.e07880.bad\n\n  defines function\n\n    greeting()\n      <- rtn as String: \"hello\"\n\n    greetAll()\n      stdout <- Stdout()\n\n      //call calls the functions flowing through it; it takes none of its own\n      cat [greeting] | call greeting > stdout","expectedOutput":null,"kind":"bad","errors":["E07880"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07880/good.ek9","url":"https://ek9.io/errors/E07880.html","title":"Write 'call' on its own","code":"#!ek9\ndefines module error.e07880.good\n\n  defines function\n\n    greeting()\n      <- rtn as String: \"hello\"\n\n    greetAll()\n      stdout <- Stdout()\n      cat [greeting] | call > stdout","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07880"}
{"id":"errors/E07890/bad.ek9","url":"https://ek9.io/errors/E07890.html","title":"E07890: not mutable","code":"#!ek9\ndefines module error.e07890.bad\n\n  defines constant\n    NAME <- \"STEVE\"\n    START_DATE <- 2023-11-03\n\n  defines function\n\n    changeConstants()\n\n      //A constant never changes\n      START_DATE += P2D\n\n      NAME: \"Stephen\"","expectedOutput":null,"kind":"bad","errors":["E07890"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07890/good.ek9","url":"https://ek9.io/errors/E07890.html","title":"Copy the constant into a variable, and change that","code":"#!ek9\ndefines module error.e07890.good\n\n  defines constant\n    NAME <- \"STEVE\"\n    START_DATE <- 2023-11-03\n\n  defines function\n\n    nextWeek()\n      <- rtn as Date: START_DATE\n\n      //A variable, copied from the constant, can change\n      rtn += P1W\n\n    fullName()\n      <- rtn as String: NAME + \" Limb\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07890"}
{"id":"errors/E07895/bad.ek9","url":"https://ek9.io/errors/E07895.html","title":"E07895: cannot assign to a method-call result - not an assignable target; only mutating operators (+=, -=, :~:, :^:, :=:) apply to a call result","code":"#!ek9\ndefines module error.e07895.bad\n\n  defines class\n    Holder\n      count <- 0\n\n      current()\n        <- rtn as Integer: count\n\n      default operator ?\n\n  defines function\n\n    assignToCallResult()\n      -> holder as Holder\n\n      //A call result is a value, not somewhere to store one\n      holder.current() := 99","expectedOutput":null,"kind":"bad","errors":["E07895"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07895/good.ek9","url":"https://ek9.io/errors/E07895.html","title":"Mutate it in place, or assign it to a variable first","code":"#!ek9\ndefines module error.e07895.good\n\n  defines class\n    Holder\n      count <- 0\n\n      current()\n        <- rtn as Integer: count\n\n      default operator ?\n\n  defines function\n\n    useCallResult()\n      -> holder as Holder\n      <- rtn as Integer: 0\n\n      //Mutate the returned object in place with a mutating operator\n      holder.current() += 1\n\n      //Or take it into a variable and work on that\n      rtn: holder.current()\n      rtn += 99","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07895"}
{"id":"errors/E07900/bad.ek9","url":"https://ek9.io/errors/E07900.html","title":"E07900: Invalid value","code":"#!ek9\ndefines module error.e07900.bad\n\n  //Invalid: uppercase base (should be lowercase)\n  defines text for \"EN\"\n\n    TestText1\n      welcome()\n        \"Welcome\"\n\n  //Invalid: uppercase base with country code\n  defines text for \"EN_US\"\n\n    TestText2\n      greeting()\n        \"Hello\"\n\n  //Invalid: hyphen instead of underscore\n  defines text for \"en-US\"\n\n    TestText3\n      message()\n        \"Hi there\"\n\n  //Invalid: lowercase country code\n  defines text for \"en_us\"\n\n    TestText4\n      welcome()\n        \"Welcome\"","expectedOutput":null,"kind":"bad","errors":["E07900"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07900/good.ek9","url":"https://ek9.io/errors/E07900.html","title":"Use the language_COUNTRY form","code":"#!ek9\ndefines module error.e07900.good\n\n  //A language code is lowercase; a country code, after '_', is uppercase\n  defines text for \"en\"\n\n    WelcomeText\n      welcome()\n        \"Welcome\"\n\n  defines text for \"en_US\"\n\n    WelcomeText\n      welcome()\n        \"Hi there\"\n\n  defines text for \"en_GB\"\n\n    WelcomeText\n      welcome()\n        \"Hello\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07900"}
{"id":"errors/E07901/bad.ek9","url":"https://ek9.io/errors/E07901.html","title":"E07901: a double-quoted String is never interpolated - '${' needs a backtick String","code":"#!ek9\ndefines module error.e07901.bad\n\n  defines program\n\n    DoubleQuotedInterpolation()\n      stdout <- Stdout()\n      count <- 2\n\n      //Invalid: a double-quoted String is never interpolated\n      stdout.println(\"${count} items\")\n\n      //Invalid: an expression is no different\n      total <- \"Total: ${count * 2}\"\n\n      //Invalid: a backslash is not an escape for '$' in a double-quoted String, so this still holds '${'\n      escaped <- \"\\${count} items\"\n\n      //Valid: a '$' that opens no interpolation is plain text in a double-quoted String\n      price <- \"Price: $42\"\n\n      //Valid: a backtick String interpolates, and '\\$' in one keeps the literal text\n      interpolated <- `${count} items`\n      literal <- `\\${count} items`\n\n      stdout.println(total + escaped + price + interpolated + literal)\n\n  defines text for \"en\"\n\n    ItemText\n\n      itemsInBasket()\n        -> count as Integer\n        //Invalid: a text body's double-quoted String is no different\n        \"${count} items in your basket\"","expectedOutput":null,"kind":"bad","errors":["E07901"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07901/good.ek9","url":"https://ek9.io/errors/E07901.html","title":"Use a backtick String","code":"#!ek9\ndefines module error.e07901.good\n\n  defines program\n\n    CountItems()\n      stdout <- Stdout()\n      count <- 2\n\n      //A backtick String interpolates\n      stdout.println(`${count} items`)\n\n      //'\\$' in a backtick String keeps the literal text\n      stdout.println(`\\${count} items`)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07901"}
{"id":"errors/E07902/bad.ek9","url":"https://ek9.io/errors/E07902.html","title":"E07902: a plain \"...\" String literal is required here - a backtick String is not a compile-time literal","code":"#!ek9\ndefines module error.e07902.bad\n\n  defines constant\n\n    APP_NAME <- \"Ledger\"\n\n    GREETING <- `Welcome to ${APP_NAME}`\n\n    PLAIN_BACKTICK <- `no interpolation, still not a literal`\n\n  defines type\n\n    Code as String constrain as\n      <> `x${APP_NAME}`","expectedOutput":null,"kind":"bad","errors":["E07902"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07902/good.ek9","url":"https://ek9.io/errors/E07902.html","title":"Use a plain literal, and interpolate where it is evaluated","code":"#!ek9\ndefines module error.e07902.good\n\n  defines constant\n    APP_NAME <- \"Ledger\"\n\n  defines function\n\n    //Interpolate where the text is evaluated\n    greeting()\n      <- rtn as String: `Welcome to ${APP_NAME}`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07902"}
{"id":"errors/E07903/bad.ek9","url":"https://ek9.io/errors/E07903.html","title":"E07903: a unicode escape needs exactly four hex digits (0-9, a-f, A-F) - write \\\\u for a backslash and a 'u'","code":"#!ek9\ndefines module error.e07903.bad\n\n  defines function\n\n    escapes()\n      <- rtn as String?\n\n      signed <- \"A\\u+041B\"\n\n      negative <- \"C\\u-001D\"\n\n      tooShort <- \"T\\u004\"\n\n      inBacktick <- `L\\u+041M`\n\n      //An escaped backslash then a 'u' is two plain characters, and a real escape is still fine.\n      windowsPath <- \"C:\\\\users\\\\steve\"\n      letter <- \"\\u0041\"\n      rtn: signed + negative + tooShort + inBacktick + windowsPath + letter","expectedOutput":null,"kind":"bad","errors":["E07903"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07903/good.ek9","url":"https://ek9.io/errors/E07903.html","title":"Escape the backslash, or give four hex digits","code":"#!ek9\ndefines module error.e07903.good\n\n  defines function\n\n    //Escape the backslash...\n    home()\n      <- rtn as String: \"C:\\\\users\\\\steve\"\n\n    //...or give exactly four hex digits\n    accented()\n      <- rtn as String: \"caf\\u00e9\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07903"}
{"id":"errors/E07910/bad.ek9","url":"https://ek9.io/errors/E07910.html","title":"E07910: sanitized parameters must be String type","code":"#!ek9\ndefines module error.e07910.bad\n\n  defines function\n\n    //ERROR: Integer cannot be sanitized - only String\n    processInteger()\n      -> value as sanitized Integer\n      <- result as Integer?\n      result: value\n\n    //ERROR: Float cannot be sanitized - only String\n    processFloat()\n      -> value as sanitized Float\n      <- result as Float?\n      result: value\n\n    //ERROR: Date cannot be sanitized - only String\n    processDate()\n      -> value as sanitized Date\n      <- result as Date?\n      result: value\n\n    //ERROR: Time cannot be sanitized - only String\n    processTime()\n      -> value as sanitized Time\n      <- result as Time?\n      result: value\n\n    //ERROR: Duration cannot be sanitized - only String\n    processDuration()\n      -> value as sanitized Duration\n      <- result as Duration?\n      result: value\n\n    //ERROR: Boolean cannot be sanitized - only String\n    processBoolean()\n      -> value as sanitized Boolean\n      <- result as Boolean?\n      result: value\n\n    //VALID: String CAN be sanitized - this should NOT produce an error\n    processString()\n      -> value as sanitized String\n      <- result as String?\n      result: value","expectedOutput":null,"kind":"bad","errors":["E07910"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07910/good.ek9","url":"https://ek9.io/errors/E07910.html","title":"Use 'sanitized' only on a String parameter","code":"#!ek9\ndefines module error.e07910.good\n\n  defines function\n\n    //A String parameter can be sanitized\n    executeQuery()\n      -> sql as sanitized String\n      <- rtn as String: sql\n\n    //An Integer needs no sanitizing: text that is not a number never becomes one\n    processCount()\n      -> count as Integer\n      <- rtn as Integer: count","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07910"}
{"id":"errors/E07920/bad.ek9","url":"https://ek9.io/errors/E07920.html","title":"E07920: sanitized modifier only valid on incoming function/method parameters","code":"#!ek9\ndefines module error.e07920.bad\n\n  defines class\n\n    BadClassField\n      //ERROR: sanitized on field doesn't make sense - nothing receives a field, so nothing could clean it\n      name as sanitized String?\n\n  defines record\n\n    BadRecordField\n      //ERROR: sanitized on record field doesn't make sense\n      value as sanitized String?\n\n  defines function\n\n    //ERROR: sanitized on RETURN parameter - data flows OUT not IN\n    badReturnParameter()\n      -> input as String\n      <- result as sanitized String?\n      result: input\n\n    //ERROR: sanitized on RETURN parameter with no incoming params\n    badReturnParameterOnly()\n      <- result as sanitized String?\n      result: \"test\"\n\n    //VALID: sanitized on incoming parameter - this is correct usage\n    validIncomingParameter()\n      -> input as sanitized String\n      <- result as String?\n      result: input\n\n  defines class\n\n    TestClass\n\n      //ERROR: sanitized on method return parameter\n      badMethodReturn()\n        -> input as String\n        <- result as sanitized String?\n        result: input\n\n      //VALID: sanitized on method incoming parameter\n      validMethodParam()\n        -> input as sanitized String\n        <- result as String?\n        result: input\n\n  defines function\n\n    //ERROR: sanitized on LOCAL variable - not a parameter at all\n    badLocalVariable()\n      -> input as String\n      <- result as String?\n\n      //Local variable declaration without initialization (variableOnlyDeclaration)\n      localVar as sanitized String?\n\n      localVar: input\n      result: localVar","expectedOutput":null,"kind":"bad","errors":["E07920"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07920/good.ek9","url":"https://ek9.io/errors/E07920.html","title":"Sanitize the incoming parameter","code":"#!ek9\ndefines module error.e07920.good\n\n  defines class\n\n    UserData\n      username as String?\n\n      default private UserData()\n\n      //Sanitize the INCOMING parameter; the field is a plain String\n      UserData()\n        -> name as sanitized String\n        this.username: String(name)\n\n      default operator ?\n\n  defines function\n\n    processInput()\n      -> text as sanitized String\n      <- rtn as String: text","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07920"}
{"id":"errors/E07930/bad.ek9","url":"https://ek9.io/errors/E07930.html","title":"E07930: cannot assign from sanitized parameter - creates hidden copy semantics","code":"#!ek9\ndefines module error.e07930.bad\n\n  defines function\n\n    badDeclarationFromSanitized()\n      -> input as sanitized String\n      <- result as String?\n\n      //ERROR: Direct declaration assignment from sanitized parameter\n      local <- input\n\n      //Use local to avoid NOT_REFERENCED error\n      result: local\n\n    badReassignmentFromSanitized()\n      -> input as sanitized String\n      <- result as String?\n\n      local <- \"initial\"\n      //ERROR: Reassignment from sanitized parameter\n      local := input\n\n      result: local\n\n    badGuardedAssignmentFromSanitized()\n      -> input as sanitized String\n      <- result as String?\n\n      local <- String()\n      //ERROR: Assign-if-unset from sanitized parameter\n      local :=? input\n\n      result: local\n\n    okDirectUse()\n      -> input as sanitized String\n      <- result as String?\n\n      //OK: Using sanitized parameter directly is fine\n      result: input\n\n    okExplicitCopy()\n      -> input as sanitized String\n      <- result as String?\n\n      //OK: Explicit copy makes semantics clear\n      local <- String(input)\n      result: local\n\n    okPassToAnotherFunction()\n      -> input as sanitized String\n      <- result as String?\n\n      //OK: Passing to another function is fine\n      result: processData(input)\n\n    processData()\n      -> data as String\n      <- result as String?\n      result: data\n\n    <?-\n      BAD: Coalescing min operator could return sanitized parameter directly.\n      If input < other alphabetically, result becomes an ALIAS to input.\n    -?>\n    badCoalescingMinFromSanitized()\n      -> input as sanitized String\n      <- result as String?\n\n      other <- \"zzzzz\"\n      //ERROR: Could create alias if input is selected as minimum\n      local <- input <? other\n\n      result: local\n\n    <?-\n      BAD: Coalescing max operator could return sanitized parameter directly.\n      If input > other alphabetically, result becomes an ALIAS to input.\n    -?>\n    badCoalescingMaxFromSanitized()\n      -> input as sanitized String\n      <- result as String?\n\n      other <- \"aaaaa\"\n      //ERROR: Could create alias if input is selected as maximum\n      local <- input >? other\n\n      result: local\n\n    <?-\n      BAD: Elvis operator could return sanitized parameter directly.\n      If input is set, result becomes an ALIAS to input.\n    -?>\n    badElvisFromSanitized()\n      -> input as sanitized String\n      <- result as String?\n\n      //ERROR: Could create alias if input is set\n      local <- input ?: \"default\"\n\n      result: local\n\n    <?-\n      BAD: Ternary operator could return sanitized parameter directly.\n      If condition is true, result becomes an ALIAS to input.\n    -?>\n    badTernaryFromSanitized()\n      -> input as sanitized String\n      <- result as String?\n\n      condition <- true\n      //ERROR: Could create alias if condition selects input\n      local <- condition <- input : \"alternative\"\n\n      result: local\n\n    <?-\n      BAD: Null coalescing operator could return sanitized parameter directly.\n      If input is not null, result becomes an ALIAS to input.\n    -?>\n    badNullCoalescingFromSanitized()\n      -> input as sanitized String\n      <- result as String?\n\n      //ERROR: Could create alias if input is not null\n      local <- input ?? \"default\"\n\n      result: local\n\n    <?-\n      BAD: Coalescing LE operator could return sanitized parameter directly.\n    -?>\n    badCoalescingLEFromSanitized()\n      -> input as sanitized String\n      <- result as String?\n\n      other <- \"zzzzz\"\n      //ERROR: Could create alias if input is selected\n      local <- input <=? other\n\n      result: local\n\n    <?-\n      BAD: Coalescing GE operator could return sanitized parameter directly.\n    -?>\n    badCoalescingGEFromSanitized()\n      -> input as sanitized String\n      <- result as String?\n\n      other <- \"aaaaa\"\n      //ERROR: Could create alias if input is selected\n      local <- input >=? other\n\n      result: local\n\n\n    <?-\n      BAD: Guard in if statement could create alias to sanitized parameter.\n      The guard uses '<-' which is an assignment.\n    -?>\n    badGuardInIfFromSanitized()\n      -> input as sanitized String\n      <- result as String?\n\n      //ERROR: Guard creates alias to sanitized parameter\n      if local <- input\n        result: local\n      else\n        result: \"empty\"\n\n    <?-\n      BAD: Guard in switch statement could create alias to sanitized parameter.\n    -?>\n    badGuardInSwitchFromSanitized()\n      -> input as sanitized String\n      <- result as String?\n\n      //ERROR: Guard creates alias to sanitized parameter\n      switch local <- input\n        case \"test\"\n          result: local\n        default\n          result: \"other\"\n\n    <?-\n      BAD: An assignment pre-flow (:=) could create alias to sanitized parameter.\n      The ':=' assigns to an EXISTING variable; 'then local?' then gates on it being set.\n    -?>\n    badGuardExpressionFromSanitized()\n      -> input as sanitized String\n      <- result as String?\n\n      //Declare local first (required for the ':=' pre-flow)\n      local <- String()\n\n      //ERROR: Guard creates alias to sanitized parameter\n      if local := input then local?\n        result: local\n      else\n        result: \"empty\"","expectedOutput":null,"kind":"bad","errors":["E07930"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07930/good.ek9","url":"https://ek9.io/errors/E07930.html","title":"Copy it, or use it directly","code":"#!ek9\ndefines module error.e07930.good\n\n  defines function\n\n    //A new String made from the sanitized one\n    process() as pure\n      -> input as sanitized String\n      <- rtn as String?\n\n      localCopy <- String(input)\n      rtn: \"Processed: \" + localCopy\n\n    //Use it directly in an expression\n    query() as pure\n      -> input as sanitized String\n      <- rtn as String: \"Query: \" + input","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07930"}
{"id":"errors/E07930/good_nonpure.ek9","url":"https://ek9.io/errors/E07930.html","title":"Outside pure code, copy or merge into an initialised variable","code":"#!ek9\ndefines module error.e07930.good.nonpure\n\n  defines function\n\n    //Copy INTO an initialised variable\n    useCopyOperator()\n      -> input as sanitized String\n      <- rtn as String: String()\n      rtn :=: String(input)\n\n    //Merge INTO an initialised variable\n    useMergeOperator()\n      -> input as sanitized String\n      <- rtn as String: \"Base: \"\n      rtn :~: String(input)\n\n    //Use it directly, or pass it on\n    useDirectly()\n      -> input as sanitized String\n      stdout <- Stdout()\n      stdout.println(input)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07930"}
{"id":"errors/E07940/bad.ek9","url":"https://ek9.io/errors/E07940.html","title":"E07940: 'sanitized' cannot be dropped - the declaration this one stands in for (an overridden method or function, a dispatcher entry point, or another locale of the text) marks this parameter 'sanitized'; it may be added, never removed","code":"#!ek9\ndefines module error.e07940.bad\n\n  defines function\n\n    cleanBase() as abstract\n      -> input as sanitized String\n      <- result as String?\n\n    plainBase() as abstract\n      -> input as String\n      <- result as String?\n\n    //ERROR: the super function declares sanitized, this implementation drops it\n    dropsSanitized() is cleanBase\n      -> input as String\n      <- result as String: input\n\n    //OK: keeps the super function's sanitized\n    keepsSanitized() is cleanBase\n      -> input as sanitized String\n      <- result as String: input\n\n    //OK: an implementation may ADD sanitized - it cleans its own parameter on every route\n    addsSanitized() is plainBase\n      -> input as sanitized String\n      <- result as String: input\n\n  defines class\n\n    Base as open\n      processInput()\n        -> input as sanitized String\n        <- result as String?\n        result: input\n\n      processNormal()\n        -> input as String\n        <- result as String?\n        result: input\n\n    DerivedRemovesSanitized extends Base\n      //ERROR: Super has sanitized, override doesn't\n      override processInput()\n        -> input as String\n        <- result as String?\n        result: input\n\n    DerivedAddsSanitized extends Base\n      //OK: Super doesn't have sanitized, the override adds it\n      override processNormal()\n        -> input as sanitized String\n        <- result as String?\n        result: input\n\n    DerivedCorrect extends Base\n      //OK: Sanitized matches super\n      override processInput()\n        -> input as sanitized String\n        <- result as String?\n        result: \"Derived: \" + input\n\n      //OK: Non-sanitized matches super\n      override processNormal()\n        -> input as String\n        <- result as String?\n        result: \"Derived: \" + input\n\n    //Test multiple parameters with mixed sanitized status\n    MultiParamBase as open\n      //First param sanitized, second not\n      processTwo()\n        ->\n          first as sanitized String\n          second as String\n        <- result as String?\n        result: first + second\n\n      //Both params sanitized\n      processBothSanitized()\n        ->\n          first as sanitized String\n          second as sanitized String\n        <- result as String?\n        result: first + second\n\n      //Neither param sanitized\n      processNeitherSanitized()\n        ->\n          first as String\n          second as String\n        <- result as String?\n        result: first + second\n\n    //ERROR: Swapped sanitized - dropping it from first is an error, adding it to second is allowed\n    DerivedSwapsSanitized extends MultiParamBase\n      override processTwo()\n        ->\n          first as String\n          second as sanitized String\n        <- result as String?\n        result: first + second\n\n    //ERROR: Removes sanitized from second param only\n    DerivedRemovesOneSanitized extends MultiParamBase\n      override processBothSanitized()\n        ->\n          first as sanitized String\n          second as String\n        <- result as String?\n        result: first + second\n\n    //OK: Adds sanitized to first param only\n    DerivedAddsOneSanitized extends MultiParamBase\n      override processNeitherSanitized()\n        ->\n          first as sanitized String\n          second as String\n        <- result as String?\n        result: first + second\n\n    //OK: Multiple params all match correctly\n    DerivedMultiParamCorrect extends MultiParamBase\n      override processTwo()\n        ->\n          first as sanitized String\n          second as String\n        <- result as String?\n        result: `Derived: ${first}${second}`\n\n      override processBothSanitized()\n        ->\n          first as sanitized String\n          second as sanitized String\n        <- result as String?\n        result: `Derived: ${first}${second}`\n\n      override processNeitherSanitized()\n        ->\n          first as String\n          second as String\n        <- result as String?\n        result: `Derived: ${first}${second}`\n\n  defines trait\n\n    PlainCleaner\n      clean() as abstract\n        -> input as String\n        <- result as String?\n\n    CleaningCleaner\n      clean() as abstract\n        -> input as sanitized String\n        <- result as String?\n\n  defines class\n\n    //OK: a trait implementation may ADD sanitized\n    StrictCleaner with trait of PlainCleaner\n      override clean()\n        -> input as sanitized String\n        <- result as String: input\n\n    //ERROR: the trait declares sanitized, this implementation drops it\n    LooseCleaner with trait of CleaningCleaner\n      override clean()\n        -> input as String\n        <- result as String: input","expectedOutput":null,"kind":"bad","errors":["E07940"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07940/good.ek9","url":"https://ek9.io/errors/E07940.html","title":"Keep 'sanitized' (adding it is fine)","code":"#!ek9\ndefines module error.e07940.good\n\n  defines class\n\n    Base as open\n      processInput()\n        -> input as sanitized String\n        stdout <- Stdout()\n        stdout.println(input)\n\n      describe()\n        -> label as String\n        stdout <- Stdout()\n        stdout.println(label)\n\n    Derived extends Base\n      //Keeps the super's sanitized\n      override processInput()\n        -> input as sanitized String\n        stdout <- Stdout()\n        stdout.println(`Derived: ${input}`)\n\n      //Adds sanitized to a plain super parameter\n      override describe()\n        -> label as sanitized String\n        stdout <- Stdout()\n        stdout.println(`Derived: ${label}`)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07940"}
{"id":"errors/E07941/bad.ek9","url":"https://ek9.io/errors/E07941.html","title":"E07941: 'sanitized' cannot be used on captured variables - sanitize at the original entry point","code":"#!ek9\ndefines module error.e07941.bad\n\n  defines trait\n    Greeter\n      greet()\n        -> greeting as String\n        <- rtn as String: greeting\n\n  defines function\n\n    //ERROR: sanitized on a dynamic class capture\n    badDynamicClassCapture()\n      -> userInput as String\n      greeter <- (sanitized userInput) with trait of Greeter as class\n      stdout <- Stdout()\n      stdout.println(greeter.greet(userInput))","expectedOutput":null,"kind":"bad","errors":["E07941"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07941/good.ek9","url":"https://ek9.io/errors/E07941.html","title":"Sanitize at the entry point","code":"#!ek9\ndefines module error.e07941.good\n\n  defines trait\n    Greeter\n      greet()\n        -> greeting as String\n        <- rtn as String: greeting\n\n  defines function\n\n    //Sanitize at the entry point; the capture receives clean data\n    greetUser()\n      -> userInput as sanitized String\n      greeter <- () with trait of Greeter as class\n      stdout <- Stdout()\n      stdout.println(greeter.greet(userInput))","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07941"}
{"id":"errors/E07942/bad.ek9","url":"https://ek9.io/errors/E07942.html","title":"E07942: 'sanitized' is specified in the function/method definition, not at call sites","code":"#!ek9\ndefines module error.e07942.bad\n\n  defines function\n\n    //Target function - no sanitization\n    processInput()\n      -> data as String\n      stdout <- Stdout()\n      stdout.println(data)\n\n    //Target function with multiple parameters\n    processMultiple()\n      ->\n        first as String\n        second as String\n      stdout <- Stdout()\n      stdout.println(first + second)\n\n    //ERROR: sanitized on function call argument\n    badFunctionCall()\n      -> userInput as String\n      //ERROR: Caller cannot specify sanitization - that's callee's responsibility\n      processInput(sanitized userInput)\n\n    //ERROR: sanitized on one of multiple arguments\n    badMultipleArgs()\n      ->\n        input1 as String\n        input2 as String\n      processMultiple(input1, sanitized input2)\n\n    //ERROR: sanitized on first argument of multiple\n    badFirstArg()\n      ->\n        input1 as String\n        input2 as String\n      processMultiple(sanitized input1, input2)\n\n    //ERROR: sanitized with named parameter\n    badNamedArg()\n      -> userInput as String\n      processInput(data := sanitized userInput)\n\n    //CORRECT: Sanitize in the definition, not at call site\n    correctSanitizeInDefinition()\n      -> input as sanitized String\n      stdout <- Stdout()\n      stdout.println(input)\n\n    //CORRECT: Caller just passes data - sanitization automatic\n    correctCaller()\n      -> userInput as String\n      //Compiler automatically sanitizes because definition has 'sanitized'\n      correctSanitizeInDefinition(userInput)\n\n  defines class\n\n    TestClass\n\n      //Target method - no sanitization\n      handleData()\n        -> data as String\n        stdout <- Stdout()\n        stdout.println(data)\n\n    TestCaller\n\n      //ERROR: sanitized on method call argument\n      badMethodCall()\n        -> userInput as String\n        obj <- TestClass()\n        obj.handleData(sanitized userInput)\n\n  defines record\n\n    TestRecord\n      value as String?\n\n      default operator ?\n\n  defines function\n\n    //ERROR: sanitized on constructor call argument\n    badConstructorCall()\n      -> userInput as String\n      stdout <- Stdout()\n      rec <- TestRecord(sanitized userInput)\n      //Use stdout with userInput to avoid cascading errors from rec\n      stdout.println(userInput)","expectedOutput":null,"kind":"bad","errors":["E07942"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07942/good.ek9","url":"https://ek9.io/errors/E07942.html","title":"Declare 'sanitized' on the parameter","code":"#!ek9\ndefines module error.e07942.good\n\n  defines function\n\n    //The receiving parameter is sanitized\n    processInput()\n      -> text as sanitized String\n      stdout <- Stdout()\n      stdout.println(text)\n\n    doWork()\n      -> userInput as String\n\n      //The caller just passes the data\n      processInput(userInput)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07942"}
{"id":"errors/E07943/bad.ek9","url":"https://ek9.io/errors/E07943.html","title":"E07943: 'sanitized' cannot be used on variable declarations - sanitize at the function/method entry point","code":"#!ek9\ndefines module error.e07943.bad\n\n  defines function\n\n    //Helper function returning a string\n    getValue()\n      <- output as String: \"test\"\n\n    //ERROR: sanitized on arrow declaration\n    badArrowDeclaration()\n      -> userInput as String\n      //ERROR: Cannot sanitize at variable declaration\n      name <- sanitized getValue()\n      stdout <- Stdout()\n      stdout.println(name)\n\n    //ERROR: sanitized on typed declaration with := operator\n    badTypedDeclarationAssign()\n      -> userInput as String\n      //ERROR: Cannot sanitize on typed variable declaration\n      data as sanitized String := userInput\n      stdout <- Stdout()\n      stdout.println(data)\n\n    //ERROR: sanitized on typed declaration with = operator\n    badTypedDeclarationAssign2()\n      -> userInput as String\n      //ERROR: Cannot sanitize on typed variable declaration\n      data as sanitized String = userInput\n      stdout <- Stdout()\n      stdout.println(data)\n\n    //ERROR: sanitized on typed declaration with :~: operator (merge)\n    badTypedDeclarationMerge()\n      -> userInput as String\n      //ERROR: Cannot sanitize with merge operator\n      data as sanitized String :~: userInput\n      stdout <- Stdout()\n      stdout.println(data)\n\n    //CORRECT: Sanitize at entry point, not at variable declaration\n    correctSanitizedParameter()\n      -> userInput as sanitized String\n      //Assignment receives already-sanitized data\n      name <- String(userInput)\n      data as String := userInput\n      stdout <- Stdout()\n      stdout.println(name + data)","expectedOutput":null,"kind":"bad","errors":["E07943"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07943/good.ek9","url":"https://ek9.io/errors/E07943.html","title":"Sanitize at the entry points","code":"#!ek9\ndefines module error.e07943.good\n\n  defines function\n\n    //Sanitize the source function's parameter...\n    getValue()\n      -> input as sanitized String\n      <- output as String: input\n\n    //...or this function's entry point\n    process()\n      -> userInput as sanitized String\n      <- rtn as String: getValue(userInput) + String(userInput)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07943"}
{"id":"errors/E07944/bad.ek9","url":"https://ek9.io/errors/E07944.html","title":"E07944: 'sanitized' cannot be used on an extern parameter - the compiler does not generate an extern body, so nothing would clean it; the external implementation must clean its input itself","code":"#!ek9\ndefines extern module error.e07944.bad\n\n  defines class\n\n    ExternalStore\n      ExternalStore()\n\n      //ERROR: an extern method cannot promise to clean its parameter\n      store()\n        -> input as sanitized String\n        <- rtn as String?\n\n      //OK: a plain String parameter on an extern method\n      lookup()\n        -> key as String\n        <- rtn as String?\n\n  defines function\n\n    //ERROR: an extern function cannot promise to clean its parameter\n    externalClean()\n      -> input as sanitized String\n      <- rtn as String?\n\n    //OK: a plain String parameter on an extern function\n    externalEcho()\n      -> input as String\n      <- rtn as String?","expectedOutput":null,"kind":"bad","errors":["E07944"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07944/good.ek9","url":"https://ek9.io/errors/E07944.html","title":"Clean in the external implementation","code":"#!ek9\ndefines extern module error.e07944.good\n\n  defines function\n\n    //A plain parameter: the external implementation cleans its own input\n    externalClean()\n      -> input as String\n      <- rtn as String?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07944"}
{"id":"errors/E07944/good_wrapper.ek9","url":"https://ek9.io/errors/E07944.html","title":"Or wrap the call in a function with a sanitized parameter","code":"#!ek9\ndefines module error.e07944.good.wrapper\n\n  references\n    error.e07944.good::externalClean\n\n  defines function\n\n    //Or wrap the call: the compiler writes this body, so it cleans its parameter on entry\n    cleanThenStore()\n      -> input as sanitized String\n      <- rtn as String: externalClean(input)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07944"}
{"id":"errors/E07950/bad.ek9","url":"https://ek9.io/errors/E07950.html","title":"E07950: '++' and '--' are statement-only operators in EK9 - they cannot be used in expressions","code":"#!ek9\ndefines module error.e07950.bad\n\n  defines function\n\n    //=== VALID INCREMENT/DECREMENT USAGE (statements) ===\n\n    ValidIncrementStatement()\n      x <- 5\n      x++\n      require x == 6\n\n    ValidDecrementStatement()\n      x <- 5\n      x--\n      require x == 4\n\n    //=== INVALID INCREMENT EXPRESSION USAGE ===\n\n    BadIncrementAssignment1()\n      x <- 5\n      y <- x++\n\n    BadIncrementAssignment2()\n      x <- 10\n      result <- x++\n\n    //=== INVALID DECREMENT EXPRESSION USAGE ===\n\n    BadDecrementAssignment1()\n      x <- 5\n      y <- x--\n\n    BadDecrementAssignment2()\n      x <- 10\n      result <- x--\n\n    //=== INVALID IN CONDITIONALS ===\n\n    BadIncrementInCondition()\n      x <- 5\n      if x++\n        require true\n\n    BadDecrementInCondition()\n      x <- 5\n      if x--\n        require true\n\n    //=== FLOAT TYPES ===\n\n    BadFloatIncrementAssignment()\n      x <- 5.0\n      y <- x++\n\n    BadFloatDecrementAssignment()\n      x <- 5.0\n      y <- x--","expectedOutput":null,"kind":"bad","errors":["E07950"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E07950/good.ek9","url":"https://ek9.io/errors/E07950.html","title":"Use '++' and '--' as statements","code":"#!ek9\ndefines module error.e07950.good\n\n  defines function\n\n    countUp()\n      <- rtn as Integer: 5\n\n      //A statement on its own\n      rtn++\n\n    nextOf()\n      -> start as Integer\n      //An expression with no side effect\n      <- rtn as Integer: start + 1","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E07950"}
{"id":"errors/E08010/bad.ek9","url":"https://ek9.io/errors/E08010.html","title":"E08010: used before definition","code":"#!ek9\ndefines module error.e08010.bad\n\n  defines function\n\n    greeting()\n      <- rtn as String?\n      rtn: salutation + \", World\"\n      salutation <- \"Hello\"","expectedOutput":null,"kind":"bad","errors":["E08010"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08010/good.ek9","url":"https://ek9.io/errors/E08010.html","title":"Declare the variable before the line that reads it","code":"#!ek9\ndefines module error.e08010.good\n\n  defines function\n\n    greeting()\n      <- rtn as String?\n      salutation <- \"Hello\"\n      rtn: salutation + \", World\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08010"}
{"id":"errors/E08020/bad.ek9","url":"https://ek9.io/errors/E08020.html","title":"E08020: might be used before being initialised","code":"#!ek9\ndefines module error.e08020.bad\n\n  defines function\n\n    describe()\n      -> ready as Boolean\n      <- rtn as String: \"unknown\"\n      label as String?\n      if ready\n        label: \"ready\"\n      rtn: label\n\n    countOne()\n      <- rtn as Integer: 0\n      counter as Integer?\n      counter++\n      rtn: counter","expectedOutput":null,"kind":"bad","errors":["E08020"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08020/good.ek9","url":"https://ek9.io/errors/E08020.html","title":"Give the variable a value before the paths divide","code":"#!ek9\ndefines module error.e08020.good\n\n  defines function\n\n    describe()\n      -> ready as Boolean\n      <- rtn as String: \"unknown\"\n      label <- \"not ready\"\n      if ready\n        label: \"ready\"\n      rtn: label\n\n    countOne()\n      <- rtn as Integer: 0\n      counter <- 0\n      counter++\n      rtn: counter","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08020"}
{"id":"errors/E08020/good_every_path.ek9","url":"https://ek9.io/errors/E08020.html","title":"Or assign it on every path","code":"#!ek9\ndefines module error.e08020.good.every.path\n\n  defines function\n\n    describe()\n      -> ready as Boolean\n      <- rtn as String: \"unknown\"\n      label as String?\n      if ready\n        label: \"ready\"\n      else\n        label: \"not ready\"\n      rtn: label","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08020"}
{"id":"errors/E08030/bad.ek9","url":"https://ek9.io/errors/E08030.html","title":"E08030: has not been checked before access","code":"#!ek9\ndefines module error.e08030.bad\n\n  defines function\n\n    nameOf()\n      -> maybe as Optional of String\n      <- rtn as String: \"nobody\"\n      rtn: maybe.get()\n\n    unsafeForms()\n      ->\n        o as Optional of Integer\n        first as Boolean\n        second as Boolean\n        limit as Integer\n      <- rtn as Integer: 0\n      //A copy of the check is not a guard\n      hasValue <- o?\n      if hasValue\n        rtn += o.get()\n      //No protection at all\n      rtn += o.get()\n      //A '?' under 'or', 'not' or a call argument proves nothing\n      if (o? and first) or (o? and second)\n        rtn += o.get()\n      //The access runs BEFORE its check\n      if o.get() > limit and o?\n        rtn += 1","expectedOutput":null,"kind":"bad","errors":["E08030"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08030/good.ek9","url":"https://ek9.io/errors/E08030.html","title":"Check that it is set first","code":"#!ek9\ndefines module error.e08030.good\n\n  defines function\n\n    nameOf()\n      -> maybe as Optional of String\n      <- rtn as String: \"nobody\"\n      if maybe?\n        rtn: maybe.get()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08030"}
{"id":"errors/E08030/good_forms.ek9","url":"https://ek9.io/errors/E08030.html","title":"Every form that checks before it reads, in the same construct","code":"#!ek9\ndefines module error.e08030.good.forms\n\n  defines function\n\n    maybeCount()\n      <- rtn as Optional of Integer: Optional(2)\n\n    safeForms()\n      ->\n        o as Optional of Integer\n        r as Result of (Integer, String)\n        limit as Integer\n      <- rtn as Integer: 0\n      checked <- Optional() of Integer\n      //Inside the block the check protects\n      if o?\n        rtn += o.get()\n      //isOk() guards ok()\n      if r.isOk()\n        rtn += r.ok()\n      //A guard checks implicitly\n      if found <- maybeCount()\n        rtn += found.get()\n      //hasNext() guards next()\n      if iter <- o.iterator() then iter.hasNext()\n        rtn += iter.next()\n      //A top-level 'and' conjunct proves it\n      if checked := maybeCount() then checked? and (rtn < limit)\n        rtn += checked.get()\n      //An earlier conjunct protects a later one\n      if o? and o.get() > limit\n        rtn += o.get()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08030"}
{"id":"errors/E08040/bad.ek9","url":"https://ek9.io/errors/E08040.html","title":"E08040: Reassignment/mutation within possible 'safe method access' scope is not allowed","code":"#!ek9\ndefines module error.e08040.bad\n\n  defines function\n\n    describe()\n      ->\n        primary as Optional of String\n        fallback as Optional of String\n      <- rtn as String: \"none\"\n      chosen <- primary\n      if chosen?\n        chosen: fallback\n        rtn: chosen.get()","expectedOutput":null,"kind":"bad","errors":["E08040"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08040/good.ek9","url":"https://ek9.io/errors/E08040.html","title":"Use the checked value; check the other one separately","code":"#!ek9\ndefines module error.e08040.good\n\n  defines function\n\n    describe()\n      ->\n        primary as Optional of String\n        fallback as Optional of String\n      <- rtn as String: \"none\"\n      if primary?\n        rtn: primary.get()\n      else if fallback?\n        rtn: fallback.get()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08040"}
{"id":"errors/E08050/bad.ek9","url":"https://ek9.io/errors/E08050.html","title":"E08050: return value is not always initialised","code":"#!ek9\ndefines module error.e08050.bad\n\n  defines function\n\n    grade()\n      -> passed as Boolean\n      <- rtn as String?\n      if passed\n        rtn: \"pass\"","expectedOutput":null,"kind":"bad","errors":["E08050"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08050/good.ek9","url":"https://ek9.io/errors/E08050.html","title":"Initialise the returning variable where it is declared","code":"#!ek9\ndefines module error.e08050.good\n\n  defines function\n\n    grade()\n      -> passed as Boolean\n      <- rtn as String: \"fail\"\n      if passed\n        rtn: \"pass\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08050"}
{"id":"errors/E08050/good_every_path.ek9","url":"https://ek9.io/errors/E08050.html","title":"Or assign it on every path","code":"#!ek9\ndefines module error.e08050.good.every.path\n\n  defines function\n\n    grade()\n      -> passed as Boolean\n      <- rtn as String?\n      if passed\n        rtn: \"pass\"\n      else\n        rtn: \"fail\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08050"}
{"id":"errors/E08055/bad.ek9","url":"https://ek9.io/errors/E08055.html","title":"E08055: return value is initialised before a 'require' precondition; declare it 'as Type?' and assign it after the require(s)","code":"#!ek9\ndefines module error.e08055.bad\n\n  defines function\n\n    unitPrice()\n      ->\n        total as Integer\n        quantity as Integer\n      <- rtn as Integer: total / quantity\n      require quantity <> 0","expectedOutput":null,"kind":"bad","errors":["E08055"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08055/good.ek9","url":"https://ek9.io/errors/E08055.html","title":"Declare it unset, require first, then compute","code":"#!ek9\ndefines module error.e08055.good\n\n  defines function\n\n    unitPrice()\n      ->\n        total as Integer\n        quantity as Integer\n      <- rtn as Integer?\n      require quantity <> 0\n      rtn: total / quantity","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08055"}
{"id":"errors/E08056/bad.ek9","url":"https://ek9.io/errors/E08056.html","title":"E08056: a guard can skip the stream, but a stream expression has no way to declare the value produced on the skip path; use the statement form with your own accumulator","code":"#!ek9\ndefines module error.e08056.bad\n\n  defines function\n\n    maybeLimit() as pure\n      <- rtn as Integer: Integer()\n\n    total()\n      <- rtn as Integer?\n      rtn: for limit <- maybeLimit() then i in 1 ... limit | collect as Integer","expectedOutput":null,"kind":"bad","errors":["E08056"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08056/good.ek9","url":"https://ek9.io/errors/E08056.html","title":"Use the statement form with your own accumulator","code":"#!ek9\ndefines module error.e08056.good\n\n  defines function\n\n    maybeLimit() as pure\n      <- rtn as Integer: Integer()\n\n    total()\n      <- rtn as Integer: 0\n      for limit <- maybeLimit() then i in 1 ... limit\n        rtn += i","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08056"}
{"id":"errors/E08056/good_forms.ek9","url":"https://ek9.io/errors/E08056.html","title":"Or hoist the guard into an 'if'; a guarded switch declares its own result","code":"#!ek9\ndefines module error.e08056.good.forms\n\n  defines function\n    maybeLimit() as pure\n      <- rtn as Integer: Integer()\n\n    hoisted()\n      <- rtn as List of Integer: List()\n      if limit <- maybeLimit()\n        rtn: for i in 1 ... limit | collect as List of Integer\n\n    described()\n      <- rtn as String?\n      rtn: switch limit <- maybeLimit() with limit\n        <- result as String: \"no limit\"\n        case 1\n          result: \"one\"\n        default\n          result: \"several\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08056"}
{"id":"errors/E08060/bad.ek9","url":"https://ek9.io/errors/E08060.html","title":"E08060: is/may not be initialised before use","code":"#!ek9\ndefines module error.e08060.bad\n\n  defines class\n\n    Stock\n      available as Integer: total - reserved\n      reserved as Integer: 2\n      total as Integer: 12\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E08060"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08060/good.ek9","url":"https://ek9.io/errors/E08060.html","title":"Declare and initialise each property before one that reads it","code":"#!ek9\ndefines module error.e08060.good\n\n  defines class\n\n    Stock\n      reserved as Integer: 2\n      total as Integer: 12\n      available as Integer: total - reserved\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08060"}
{"id":"errors/E08061/bad.ek9","url":"https://ek9.io/errors/E08061.html","title":"E08061: the object is used before it is fully constructed - set every property before calling its methods","code":"#!ek9\ndefines module error.e08061.bad\n\n  defines class\n\n    Gauge\n      reading as Integer?\n      doubled as Integer?\n\n      Gauge()\n        doubled: twice()\n        reading: 21\n\n      twice()\n        <- rtn as Integer: reading * 2\n\n      default operator ?\n\n    Document\n      title as String?\n      section as Part?\n\n      default private Document()\n\n      Document()\n        -> text as String\n        section :=? (owner: this) with trait of Part as class\n          override describe() as pure\n            <- rtn as String: `a section of ${owner.name()}`\n          default operator ?\n        title: text\n\n      name() as pure\n        <- rtn as String: title\n\n      default operator ?\n\n  defines trait\n\n    Part\n      describe() as pure\n        <- rtn as String?","expectedOutput":null,"kind":"bad","errors":["E08061"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08061/good.ek9","url":"https://ek9.io/errors/E08061.html","title":"Set every property before calling a method on the object","code":"#!ek9\ndefines module error.e08061.good\n\n  defines class\n\n    Gauge\n      reading as Integer?\n      doubled as Integer: 0\n\n      Gauge()\n        reading: 21\n        doubled: twice()\n\n      twice()\n        <- rtn as Integer: reading * 2\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08061"}
{"id":"errors/E08061/good_parent_link.ek9","url":"https://ek9.io/errors/E08061.html","title":"The parent link: capture this only once every other property is set","code":"#!ek9\ndefines module error.e08061.good.parent.link\n\n  defines class\n\n    Document\n      title as String?\n      section as Part?\n\n      default private Document()\n\n      Document()\n        -> text as String\n        title: text\n        section :=? (owner: this) with trait of Part as class\n          override describe() as pure\n            <- rtn as String: `a section of ${owner.name()}`\n          default operator ?\n\n      name() as pure\n        <- rtn as String: title\n\n      default operator ?\n\n  defines trait\n\n    Part\n      describe() as pure\n        <- rtn as String?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08061"}
{"id":"errors/E08070/bad.ek9","url":"https://ek9.io/errors/E08070.html","title":"E08070: never initialised","code":"#!ek9\ndefines module error.e08070.bad\n\n  defines class\n\n    Ledger\n      owner as String?\n\n      default private Ledger()\n\n      describe()\n        <- rtn as String: \"ledger\"\n\n      override operator ? as pure\n        <- rtn as Boolean: true","expectedOutput":null,"kind":"bad","errors":["E08070"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08070/good.ek9","url":"https://ek9.io/errors/E08070.html","title":"Initialise the property where it is declared","code":"#!ek9\ndefines module error.e08070.good\n\n  defines class\n\n    Ledger\n      owner as String: \"unassigned\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08070"}
{"id":"errors/E08070/good_constructor.ek9","url":"https://ek9.io/errors/E08070.html","title":"Or set it in a constructor","code":"#!ek9\ndefines module error.e08070.good.constructor\n\n  defines class\n\n    Ledger\n      owner as String?\n\n      default private Ledger()\n\n      Ledger()\n        -> name as String\n        owner: name\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08070"}
{"id":"errors/E08080/bad.ek9","url":"https://ek9.io/errors/E08080.html","title":"E08080: self assignment","code":"#!ek9\ndefines module error.e08080.bad\n\n  defines function\n\n    tidy()\n      -> name as String\n      <- rtn as String: name.trim()\n      rtn: rtn\n\n    copyOver()\n      <- rtn as String: \"draft\"\n      rtn :=: rtn","expectedOutput":null,"kind":"bad","errors":["E08080"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08080/good.ek9","url":"https://ek9.io/errors/E08080.html","title":"Assign the value you meant - here, a different variable","code":"#!ek9\ndefines module error.e08080.good\n\n  defines function\n\n    tidy()\n      -> name as String\n      <- rtn as String: name.trim()\n\n    copyOver()\n      -> source as String\n      <- rtn as String: \"draft\"\n      rtn :=: source","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08080"}
{"id":"errors/E08081/bad.ek9","url":"https://ek9.io/errors/E08081.html","title":"E08081: comparing a value to itself is always constant and indicates a logic error","code":"#!ek9\ndefines module error.e08081.bad\n\n  defines function\n\n    checkEquality()\n      -> amount as Integer\n      <- result as Boolean?\n\n      result: amount == amount\n\n    checkNotEqual()\n      -> amount as Integer\n      <- result as Boolean?\n\n      result: amount <> amount\n\n    checkNotEqual2()\n      -> amount as Integer\n      <- result as Boolean?\n\n      result: amount != amount\n\n    checkLessThan()\n      -> amount as Integer\n      <- result as Boolean?\n\n      result: amount < amount\n\n    checkGreaterThan()\n      -> amount as Integer\n      <- result as Boolean?\n\n      result: amount > amount\n\n    checkLessEqual()\n      -> amount as Integer\n      <- result as Boolean?\n\n      result: amount <= amount\n\n    checkGreaterEqual()\n      -> amount as Integer\n      <- result as Boolean?\n\n      result: amount >= amount\n\n    checkComparator()\n      -> amount as Integer\n      <- result as Integer?\n\n      result: amount <=> amount\n\n    checkFuzzy()\n      -> greeting as String\n      <- result as Integer?\n\n      result: greeting <~> greeting\n\n    checkContains()\n      -> greeting as String\n      <- result as Boolean?\n\n      result: greeting contains greeting\n\n    checkConstantComparison()\n      <- result as Boolean?\n\n      result: MAX_RETRIES == MAX_RETRIES\n\n  defines constant\n\n    MAX_RETRIES <- 10","expectedOutput":null,"kind":"bad","errors":["E08081"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08081/good.ek9","url":"https://ek9.io/errors/E08081.html","title":"Compare two different values","code":"#!ek9\ndefines module error.e08081.good\n\n  defines function\n\n    compareDifferentVars()\n      ->\n        first as Integer\n        second as Integer\n      <- result as Boolean?\n\n      result: first == second\n\n    compareDifferentStrings()\n      ->\n        firstName as String\n        lastName as String\n      <- result as Boolean?\n\n      result: firstName <> lastName\n\n    compareRelational()\n      ->\n        first as Integer\n        second as Integer\n      <- result as Boolean?\n\n      result: first < second\n\n    compareComparator()\n      ->\n        first as Integer\n        second as Integer\n      <- result as Integer?\n\n      result: first <=> second\n\n    compareFuzzy()\n      ->\n        firstName as String\n        lastName as String\n      <- result as Integer?\n\n      result: firstName <~> lastName\n\n    compareContains()\n      ->\n        sentence as String\n        keyword as String\n      <- result as Boolean?\n\n      result: sentence contains keyword","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08081"}
{"id":"errors/E08082/bad.ek9","url":"https://ek9.io/errors/E08082.html","title":"E08082: comparison between literal values has a predetermined result","code":"#!ek9\ndefines module error.e08082.bad\n\n  defines function\n\n    checkIntegerEqual()\n      <- result as Boolean?\n\n      result: 1 == 1\n\n    checkIntegerNotEqual()\n      <- result as Boolean?\n\n      result: 1 <> 2\n\n    checkStringEqual()\n      <- result as Boolean?\n\n      result: \"hello\" == \"hello\"\n\n    checkStringNotEqual()\n      <- result as Boolean?\n\n      result: \"hello\" <> \"world\"\n\n    checkBooleanEqual()\n      <- result as Boolean?\n\n      result: true == false\n\n    checkFloatLessThan()\n      <- result as Boolean?\n\n      result: 1.0 < 2.0\n\n    checkCharEqual()\n      <- result as Boolean?\n\n      result: 'a' == 'a'","expectedOutput":null,"kind":"bad","errors":["E08082"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08082/good.ek9","url":"https://ek9.io/errors/E08082.html","title":"Compare a variable, not two literals","code":"#!ek9\ndefines module error.e08082.good\n\n  defines function\n\n    compareVariableWithLiteral()\n      -> amount as Integer\n      <- result as Boolean?\n\n      result: amount == 1\n\n    compareTwoVariables()\n      ->\n        first as Integer\n        second as Integer\n      <- result as Boolean?\n\n      result: first == second\n\n    compareDifferentStrings()\n      ->\n        firstName as String\n        lastName as String\n      <- result as Boolean?\n\n      result: firstName <> lastName\n\n    compareRelational()\n      ->\n        first as Integer\n        second as Integer\n      <- result as Boolean?\n\n      result: first < second","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08082"}
{"id":"errors/E08083/bad.ek9","url":"https://ek9.io/errors/E08083.html","title":"E08083: arithmetic expression always produces a constant result","code":"#!ek9\ndefines module error.e08083.bad\n\n  defines function\n\n    checkSubtractSelf()\n      -> amount as Integer\n      <- result as Integer?\n\n      result: amount - amount\n\n    checkDivideSelf()\n      -> amount as Integer\n      <- result as Integer?\n\n      result: amount / amount\n\n    checkModSelf()\n      -> amount as Integer\n      <- result as Integer?\n\n      result: amount mod amount\n\n    checkRemSelf()\n      -> amount as Integer\n      <- result as Integer?\n\n      result: amount rem amount\n\n    checkModOne()\n      -> amount as Integer\n      <- result as Integer?\n\n      result: amount mod 1\n\n    checkRemOne()\n      -> amount as Integer\n      <- result as Integer?\n\n      result: amount rem 1","expectedOutput":null,"kind":"bad","errors":["E08083"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08083/good.ek9","url":"https://ek9.io/errors/E08083.html","title":"Arithmetic whose result depends on its operands","code":"#!ek9\ndefines module error.e08083.good\n\n  defines function\n\n    addSelf()\n      -> amount as Integer\n      <- result as Integer?\n\n      result: amount + amount\n\n    multiplySelf()\n      -> amount as Integer\n      <- result as Integer?\n\n      result: amount * amount\n\n    subtractDifferent()\n      ->\n        first as Integer\n        second as Integer\n      <- result as Integer?\n\n      result: first - second\n\n    modTwo()\n      -> amount as Integer\n      <- result as Integer?\n\n      result: amount mod 2\n\n    divideByTwo()\n      -> amount as Integer\n      <- result as Integer?\n\n      result: amount / 2","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08083"}
{"id":"errors/E08084/bad.ek9","url":"https://ek9.io/errors/E08084.html","title":"E08084: comparing a Boolean with true/false is redundant","code":"#!ek9\ndefines module error.e08084.bad\n\n  defines function\n\n    checkEqualTrue()\n      -> ready as Boolean\n      <- result as Boolean?\n\n      result: ready == true\n\n    checkNotEqualTrue()\n      -> ready as Boolean\n      <- result as Boolean?\n\n      result: ready <> true\n\n    checkEqualFalse()\n      -> ready as Boolean\n      <- result as Boolean?\n\n      result: ready == false\n\n    checkNotEqualFalse()\n      -> ready as Boolean\n      <- result as Boolean?\n\n      result: ready <> false\n\n    checkReversedTrueEqual()\n      -> ready as Boolean\n      <- result as Boolean?\n\n      result: true == ready","expectedOutput":null,"kind":"bad","errors":["E08084"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08084/good.ek9","url":"https://ek9.io/errors/E08084.html","title":"Use the Boolean directly, or with not","code":"#!ek9\ndefines module error.e08084.good\n\n  defines function\n\n    compareTwoBooleans()\n      ->\n        first as Boolean\n        second as Boolean\n      <- result as Boolean?\n\n      result: first == second\n\n    useBooleanDirectly()\n      -> ready as Boolean\n      <- result as Boolean?\n\n      result: ready\n\n    useNegatedBoolean()\n      -> ready as Boolean\n      <- result as Boolean?\n\n      result: not ready","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08084"}
{"id":"errors/E08085/bad.ek9","url":"https://ek9.io/errors/E08085.html","title":"E08085: logical expression is always true or always false","code":"#!ek9\ndefines module error.e08085.bad\n\n  defines function\n\n    checkOrNotTautology()\n      -> isEnabled as Boolean\n      <- result as Boolean?\n\n      result: isEnabled or not isEnabled\n\n    checkAndNotContradiction()\n      -> isEnabled as Boolean\n      <- result as Boolean?\n\n      result: isEnabled and not isEnabled\n\n    checkNotOrTautology()\n      -> isEnabled as Boolean\n      <- result as Boolean?\n\n      result: not isEnabled or isEnabled\n\n    checkNotAndContradiction()\n      -> isEnabled as Boolean\n      <- result as Boolean?\n\n      result: not isEnabled and isEnabled","expectedOutput":null,"kind":"bad","errors":["E08085"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08085/good.ek9","url":"https://ek9.io/errors/E08085.html","title":"Combine different conditions","code":"#!ek9\ndefines module error.e08085.good\n\n  defines function\n\n    orDifferentVars()\n      ->\n        first as Boolean\n        second as Boolean\n      <- result as Boolean?\n\n      result: first or second\n\n    andNotDifferentVar()\n      ->\n        first as Boolean\n        second as Boolean\n      <- result as Boolean?\n\n      result: first and not second\n\n    bothNegatedDifferent()\n      ->\n        first as Boolean\n        second as Boolean\n      <- result as Boolean?\n\n      result: not first or not second","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08085"}
{"id":"errors/E08086/bad.ek9","url":"https://ek9.io/errors/E08086.html","title":"E08086: condition is always true based on data flow analysis","code":"#!ek9\ndefines module error.e08086.bad\n\n  defines constant\n    MANY <- 10\n    SEVERAL <- 6\n\n  defines function\n\n    classify()\n      -> count as Integer\n      <- rtn as String: \"few\"\n      if count > MANY\n        if count > SEVERAL\n          rtn: \"many\"\n\n    describe()\n      <- rtn as String: \"unknown\"\n      enabled <- false\n      if not enabled\n        rtn: \"disabled\"","expectedOutput":null,"kind":"bad","errors":["E08086"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08086/good.ek9","url":"https://ek9.io/errors/E08086.html","title":"Test only what is not already known","code":"#!ek9\ndefines module error.e08086.good\n\n  defines constant\n    MANY <- 10\n\n  defines function\n\n    classify()\n      -> count as Integer\n      <- rtn as String: \"few\"\n      if count > MANY\n        rtn: \"many\"\n\n    describe()\n      -> enabled as Boolean\n      <- rtn as String: \"enabled\"\n      if not enabled\n        rtn: \"disabled\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08086"}
{"id":"errors/E08087/bad.ek9","url":"https://ek9.io/errors/E08087.html","title":"E08087: condition is always false based on data flow analysis","code":"#!ek9\ndefines module error.e08087.bad\n\n  defines constant\n    MANY <- 10\n    FEW <- 3\n\n  defines function\n\n    classify()\n      -> count as Integer\n      <- rtn as String: \"some\"\n      if count > MANY and count < FEW\n        rtn: \"impossible\"\n\n    describe()\n      <- rtn as String: \"unknown\"\n      status <- \"ready\"\n      if status == \"error\"\n        rtn: \"failed\"","expectedOutput":null,"kind":"bad","errors":["E08087"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08087/good.ek9","url":"https://ek9.io/errors/E08087.html","title":"Test a value that can vary","code":"#!ek9\ndefines module error.e08087.good\n\n  defines constant\n    MANY <- 10\n    FEW <- 3\n\n  defines function\n\n    classify()\n      -> count as Integer\n      <- rtn as String: \"some\"\n      if count > MANY or count < FEW\n        rtn: \"outside\"\n\n    describe()\n      -> status as String\n      <- rtn as String: \"unknown\"\n      if status == \"error\"\n        rtn: \"failed\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08087"}
{"id":"errors/E08088/bad.ek9","url":"https://ek9.io/errors/E08088.html","title":"E08088: isSet check is always true based on data flow analysis","code":"#!ek9\ndefines module error.e08088.bad\n\n  defines function\n\n    checkStringLiteralAlwaysSet()\n      <- result as String: String()\n\n      greeting <- \"hello\"\n\n      if greeting?\n        result: greeting\n\n    checkIntegerLiteralAlwaysSet()\n      <- result as String: String()\n\n      count <- 42\n\n      if count?\n        result: $count\n\n    checkBooleanLiteralAlwaysSet()\n      <- result as String: String()\n\n      isEnabled <- true\n\n      if isEnabled?\n        result: $isEnabled","expectedOutput":null,"kind":"bad","errors":["E08088"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08088/good.ek9","url":"https://ek9.io/errors/E08088.html","title":"Use a value that is known to be set directly","code":"#!ek9\ndefines module error.e08088.good\n\n  defines function\n\n    checkStringLiteralAlwaysSet()\n      <- result as String: String()\n      greeting <- \"hello\"\n      result: greeting\n\n    checkMaybeSet()\n      -> greeting as String\n      <- result as String: String()\n      if greeting?\n        result: greeting","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08088"}
{"id":"errors/E08089/bad.ek9","url":"https://ek9.io/errors/E08089.html","title":"E08089: isSet check is always false based on data flow analysis","code":"#!ek9\ndefines module error.e08089.bad\n\n  defines function\n\n    computeName()\n      <- rtn as String: \"Alice\"\n\n    computeCount()\n      <- rtn as Integer: 42\n\n    //Else of isSet narrows to UNSET, re-checking is always false\n    checkNeverSetInElse()\n      <- result as String: \"no-name-found\"\n\n      name <- computeName()\n      if name?\n        result: name\n      else\n        if name?\n          result: \"unreachable-name-branch\"\n\n    //Same pattern with Integer variable\n    checkNeverSetIntegerElse()\n      <- result as String: \"no-count-found\"\n\n      count <- computeCount()\n      if count?\n        result: $count\n      else\n        if count?\n          result: \"unreachable-count-branch\"","expectedOutput":null,"kind":"bad","errors":["E08089"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08089/good.ek9","url":"https://ek9.io/errors/E08089.html","title":"Do not re-test what the else already decided","code":"#!ek9\ndefines module error.e08089.good\n\n  defines function\n\n    computeName()\n      <- rtn as String: \"Alice\"\n\n    checkName()\n      <- result as String: \"no-name-found\"\n      name <- computeName()\n      if name?\n        result: name","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08089"}
{"id":"errors/E08090/bad.ek9","url":"https://ek9.io/errors/E08090.html","title":"E08090: is not referenced anywhere, or not referenced after assignment","code":"#!ek9\ndefines module error.e08090.bad\n\n  defines function\n\n    area()\n      ->\n        width as Integer\n        height as Integer\n      <- rtn as Integer: width * height\n      border <- 2\n\n    label()\n      <- rtn as String: \"plain\"\n      suffix as String?","expectedOutput":null,"kind":"bad","errors":["E08090"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08090/good.ek9","url":"https://ek9.io/errors/E08090.html","title":"Remove the variable, or use it","code":"#!ek9\ndefines module error.e08090.good\n\n  defines function\n\n    area()\n      ->\n        width as Integer\n        height as Integer\n      <- rtn as Integer: width * height\n\n    framedArea()\n      ->\n        width as Integer\n        height as Integer\n      <- rtn as Integer?\n      border <- 2\n      rtn: (width + border) * (height + border)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08090"}
{"id":"errors/E08091/bad.ek9","url":"https://ek9.io/errors/E08091.html","title":"E08091: parameter is declared but never used in the function/method body","code":"#!ek9\ndefines module error.e08091.bad\n\n  defines function\n\n    unusedSingleParam()\n      ->\n        ignored as String\n      <- result as String: \"done\"\n\n    unusedOneOfTwo()\n      ->\n        used as String\n        notUsed as Integer\n      <- result as String: used\n\n    usedParam()\n      -> input as String\n      <- result as String: input\n\n    abstractBase() as abstract\n      -> input as String\n      <- result as String?","expectedOutput":null,"kind":"bad","errors":["E08091"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08091/good.ek9","url":"https://ek9.io/errors/E08091.html","title":"Remove the parameter, or use it","code":"#!ek9\ndefines module error.e08091.good\n\n  defines function\n\n    singleResult()\n      <- result as String: \"done\"\n\n    bothUsed()\n      ->\n        used as String\n        count as Integer\n      <- result as String: used + $count","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08091"}
{"id":"errors/E08092/bad.ek9","url":"https://ek9.io/errors/E08092.html","title":"E08092: empty check is always true based on data flow analysis","code":"#!ek9\ndefines module error.e08092.bad\n\n  defines function\n\n    checkEmptyList()\n      <- result as String: \"has items\"\n      items <- List() of String\n      if items empty\n        result: \"empty\"","expectedOutput":null,"kind":"bad","errors":["E08092"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08092/good.ek9","url":"https://ek9.io/errors/E08092.html","title":"Check a collection whose contents are not known","code":"#!ek9\ndefines module error.e08092.good\n\n  defines function\n\n    checkEmptyList()\n      -> items as List of String\n      <- result as String: \"has items\"\n      if items empty\n        result: \"empty\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08092"}
{"id":"errors/E08093/bad.ek9","url":"https://ek9.io/errors/E08093.html","title":"E08093: empty check is always false based on data flow analysis","code":"#!ek9\ndefines module error.e08093.bad\n\n  defines function\n\n    checkListLiteral()\n      <- result as String: \"has items\"\n      numbers <- [1, 2, 3]\n      if numbers empty\n        result: \"empty\"","expectedOutput":null,"kind":"bad","errors":["E08093"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08093/good.ek9","url":"https://ek9.io/errors/E08093.html","title":"A literal list is never empty: use it, check only what may be empty","code":"#!ek9\ndefines module error.e08093.good\n\n  defines function\n\n    checkListLiteral()\n      <- result as String: \"has items\"\n      numbers <- [1, 2, 3]\n      result: `has ${length numbers} items`\n\n    checkSupplied()\n      -> numbers as List of Integer\n      <- result as String: \"has items\"\n      if numbers empty\n        result: \"empty\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08093"}
{"id":"errors/E08094/bad.ek9","url":"https://ek9.io/errors/E08094.html","title":"E08094: coalescing expression has a predetermined result - both operands are literals, or a literal on the left of '?:' is always set and so always chosen","code":"#!ek9\ndefines module error.e08094.bad\n\n  defines function\n\n    checkIntegerCoalescingLT()\n      <- result as Integer?\n\n      result: 5 <? 3\n\n    checkIntegerCoalescingGT()\n      <- result as Integer?\n\n      result: 5 >? 3\n\n    checkIntegerCoalescingLE()\n      <- result as Integer?\n\n      result: 5 <=? 3\n\n    checkIntegerCoalescingGE()\n      <- result as Integer?\n\n      result: 5 >=? 3\n\n    checkFloatCoalescingLT()\n      <- result as Float?\n\n      result: 1.0 <? 2.0\n\n    checkStringCoalescingLT()\n      <- result as String?\n\n      result: \"alpha\" <? \"beta\"\n\n    //A literal on the LEFT of '?:' is always set, so it is always the result and the right is never used.\n    checkElvisIntegerLiteralLeft()\n      -> fallback as Integer\n      <- result as Integer?\n\n      result: 7 ?: fallback\n\n    checkElvisPromotedLiteralLeft()\n      <- result as Float?\n\n      result: 7 ?: 2.5\n\n    checkElvisStringLiteralLeft()\n      -> fallback as String\n      <- result as String?\n\n      result: \"text\" ?: fallback","expectedOutput":null,"kind":"bad","errors":["E08094"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08094/good.ek9","url":"https://ek9.io/errors/E08094.html","title":"Coalesce a variable; a literal only as the fallback","code":"#!ek9\ndefines module error.e08094.good\n\n  defines function\n\n    coalesceVariableWithLiteral()\n      -> amount as Integer\n      <- result as Integer?\n\n      result: amount <? 100\n\n    coalesceTwoVariables()\n      ->\n        first as Integer\n        second as Integer\n      <- result as Integer?\n\n      result: first >? second\n\n    coalesceVariableLE()\n      ->\n        first as Integer\n        second as Integer\n      <- result as Integer?\n\n      result: first <=? second\n\n    coalesceVariableGE()\n      -> amount as Integer\n      <- result as Integer?\n\n      result: amount >=? 50\n\n    //A literal on the RIGHT of '?:' is the fallback - the left decides.\n    elvisVariableLeftLiteralRight()\n      -> amount as Integer\n      <- result as Integer?\n\n      result: amount ?: 0\n\n    //Inside require/assert a literal on the left is deliberate (as for the comparison family).\n    elvisLiteralLeftInRequire()\n      -> amount as Integer\n      require (7 ?: amount) > 0","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08094"}
{"id":"errors/E08095/bad.ek9","url":"https://ek9.io/errors/E08095.html","title":"E08095: assign-if-unset ':=?' can never apply because the target is always set - the right side is never evaluated","code":"#!ek9\ndefines module error.e08095.bad\n\n  defines record\n\n    //Both fields are given a literal value at declaration, so both are SET before the\n    //constructor body runs - every ':=?' below is dead and discards its argument.\n    LiteralDefault\n      enabled as Boolean: false\n      count as Integer: 0\n\n      LiteralDefault() as pure\n        ->\n          isEnabled as Boolean\n          howMany as Integer\n        enabled :=? isEnabled\n        count :=? howMany\n\n      default operator ?\n\n    //'this.<field>' is the form a constructor must use when the parameter shadows the field.\n    //It is tracked too, so the dead assignment is still caught.\n    ShadowedParameter\n      count as Integer: 0\n\n      ShadowedParameter() as pure\n        -> count as Integer\n        this.count :=? count\n\n      default operator ?\n\n  defines function\n\n    //The same proof on a local variable: assigned from a literal, so it is provably SET.\n    guardedOnSetLocal()\n      <- rtn as String: \"unchanged\"\n      name <- \"Alice\"\n      name :=? \"Bob\"\n      rtn: name","expectedOutput":null,"kind":"bad","errors":["E08095"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08095/good.ek9","url":"https://ek9.io/errors/E08095.html","title":"Use :=? only on something that may be unset","code":"#!ek9\ndefines module error.e08095.good\n\n  defines record\n\n    //Fields declared UNSET - so ':=?' in the pure constructor genuinely applies.\n    //This is the shape of the book's shared Coord record.\n    UnsetDefault\n      name as String: String()\n      count as Integer: Integer()\n\n      default UnsetDefault() as pure\n\n      UnsetDefault() as pure\n        ->\n          aName as String\n          aCount as Integer\n        name :=? String(aName)\n        count :=? Integer(aCount)\n\n      default operator ?\n\n    //'this.<field>' against an UNSET field is correct and must NOT be flagged.\n    ShadowedButUnset\n      count as Integer: Integer()\n\n      ShadowedButUnset() as pure\n        -> count as Integer\n        this.count :=? count\n\n      default operator ?\n\n  defines function\n\n    suppliedName()\n      <- rtn as String: \"from-call\"\n\n    //A value from a function call is UNKNOWN to data flow analysis, so neither the\n    //\"never applies\" nor the \"always applies\" proof exists - stay silent.\n    guardedOnUnknownLocal()\n      <- rtn as String: \"unchanged\"\n      candidate <- suppliedName()\n      candidate :=? \"fallback\"\n      rtn: candidate","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08095"}
{"id":"errors/E08100/bad.ek9","url":"https://ek9.io/errors/E08100.html","title":"E08100: reassignment not allowed when scope is marked as 'pure' (':=?' is supported)","code":"#!ek9\ndefines module error.e08100.bad\n\n  defines function\n\n    total() as pure\n      ->\n        price as Integer\n        quantity as Integer\n      <- rtn as Integer?\n      subtotal <- price\n      subtotal := price * quantity\n      rtn: subtotal","expectedOutput":null,"kind":"bad","errors":["E08100"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08100/good.ek9","url":"https://ek9.io/errors/E08100.html","title":"Give the variable its value where it is declared","code":"#!ek9\ndefines module error.e08100.good\n\n  defines function\n\n    total() as pure\n      ->\n        price as Integer\n        quantity as Integer\n      <- rtn as Integer?\n      subtotal <- price * quantity\n      rtn: subtotal","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08100"}
{"id":"errors/E08100/good_if_unset.ek9","url":"https://ek9.io/errors/E08100.html","title":"Or declare it unset and assign it once with :=?","code":"#!ek9\ndefines module error.e08100.good.if.unset\n\n  defines function\n\n    total() as pure\n      ->\n        price as Integer\n        quantity as Integer\n      <- rtn as Integer?\n      subtotal as Integer?\n      subtotal :=? price * quantity\n      rtn: subtotal","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08100"}
{"id":"errors/E08110/bad.ek9","url":"https://ek9.io/errors/E08110.html","title":"E08110: reassignment not allowed of an incoming argument/parameter","code":"#!ek9\ndefines module error.e08110.bad\n\n  defines function\n\n    greet()\n      -> name as String\n      <- rtn as String?\n      name :=? \"friend\"\n      rtn: \"Hello \" + name","expectedOutput":null,"kind":"bad","errors":["E08110"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08110/good.ek9","url":"https://ek9.io/errors/E08110.html","title":"Give the fallback to a new variable","code":"#!ek9\ndefines module error.e08110.good\n\n  defines function\n\n    greet()\n      -> name as String\n      <- rtn as String?\n      who <- name ?: \"friend\"\n      rtn: \"Hello \" + who","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08110"}
{"id":"errors/E08110/good_mutated.ek9","url":"https://ek9.io/errors/E08110.html","title":"Mutate the caller's object in place - only rebinding the name is refused","code":"#!ek9\ndefines module error.e08110.good.mutated\n\n  defines function\n\n    bump()\n      -> counter as Integer\n      //Allowed: the caller's Integer is now one higher\n      counter += 1\n\n  defines program\n    Count()\n      stdout <- Stdout()\n      tally <- 41\n      bump(tally)\n      stdout.println($tally)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08110"}
{"id":"errors/E08120/bad.ek9","url":"https://ek9.io/errors/E08120.html","title":"E08120: mutating variables is not allowed when scope is marked as 'pure'","code":"#!ek9\ndefines module error.e08120.bad\n\n  defines function\n\n    withReviewedTag() as pure\n      -> tags as List of String\n      <- tagged as List of String: tags\n      tags += \"reviewed\"","expectedOutput":null,"kind":"bad","errors":["E08120"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08120/good.ek9","url":"https://ek9.io/errors/E08120.html","title":"Return a new value instead of changing one","code":"#!ek9\ndefines module error.e08120.good\n\n  defines function\n\n    withReviewedTag() as pure\n      -> tags as List of String\n      <- tagged as List of String: tags + \"reviewed\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08120"}
{"id":"errors/E08130/bad.ek9","url":"https://ek9.io/errors/E08130.html","title":"E08130: is not marked 'pure', but call is made in a scope that is marked as 'pure'","code":"#!ek9\ndefines module error.e08130.bad\n\n  defines function\n\n    shout()\n      -> message as String\n      <- rtn as String: message.upperCase()\n\n    announce() as pure\n      -> message as String\n      <- rtn as String: shout(message)","expectedOutput":null,"kind":"bad","errors":["E08130"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08130/good.ek9","url":"https://ek9.io/errors/E08130.html","title":"Call only pure functions from a pure one - mark the helper pure","code":"#!ek9\ndefines module error.e08130.good\n\n  defines function\n\n    shout() as pure\n      -> message as String\n      <- rtn as String: message.upperCase()\n\n    announce() as pure\n      -> message as String\n      <- rtn as String: shout(message)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08130"}
{"id":"errors/E08140/bad.ek9","url":"https://ek9.io/errors/E08140.html","title":"E08140: component injection not allowed when scope is marked as 'pure'","code":"#!ek9\ndefines module error.e08140.bad\n\n  defines component\n\n    Timekeeper as abstract\n      now() as pure abstract\n        <- rtn as String?\n\n  defines function\n\n    stamp() as pure\n      <- rtn as String?\n      timekeeper as Timekeeper!\n      rtn: timekeeper.now()","expectedOutput":null,"kind":"bad","errors":["E08140"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08140/good.ek9","url":"https://ek9.io/errors/E08140.html","title":"Inject only where the scope is not pure","code":"#!ek9\ndefines module error.e08140.good\n\n  defines component\n\n    Timekeeper as abstract\n      now() as pure abstract\n        <- rtn as String?\n\n  defines function\n\n    stamp()\n      <- rtn as String?\n      timekeeper as Timekeeper!\n      rtn: timekeeper.now()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08140"}
{"id":"errors/E08140/good_parameter.ek9","url":"https://ek9.io/errors/E08140.html","title":"Or keep the function pure and pass the component in","code":"#!ek9\ndefines module error.e08140.good.parameter\n\n  defines component\n\n    Timekeeper as abstract\n      now() as pure abstract\n        <- rtn as String?\n\n  defines function\n\n    stamp() as pure\n      -> timekeeper as Timekeeper\n      <- rtn as String: timekeeper.now()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08140"}
{"id":"errors/E08150/bad.ek9","url":"https://ek9.io/errors/E08150.html","title":"E08150: dependency injection of a non-abstract component is not allowed, use an abstract base component","code":"#!ek9\ndefines module error.e08150.bad\n\n  defines component\n\n    Timekeeper\n      now()\n        <- time as String: \"noon\"\n\n  defines function\n\n    report()\n      <- summary as String?\n      timekeeper as Timekeeper!\n      summary: \"It is \" + timekeeper.now()","expectedOutput":null,"kind":"bad","errors":["E08150"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08150/good.ek9","url":"https://ek9.io/errors/E08150.html","title":"Inject the abstract component; the application registers the concrete one","code":"#!ek9\ndefines module error.e08150.good\n\n  defines component\n\n    Timekeeper as abstract\n      now() as abstract\n        <- time as String?\n\n    NoonTimekeeper is Timekeeper\n      override now()\n        <- time as String: \"noon\"\n\n  defines application\n\n    TimeApp\n      register NoonTimekeeper() as Timekeeper\n\n  defines program\n\n    Report() with application of TimeApp\n      timekeeper as Timekeeper!\n      Stdout().println(\"It is \" + timekeeper.now())","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08150"}
{"id":"errors/E08160/bad.ek9","url":"https://ek9.io/errors/E08160.html","title":"E08160: dependency injection is not allowed","code":"#!ek9\ndefines module error.e08160.bad\n\n  defines function\n\n    report()\n      <- rtn as String?\n      title as String!\n      rtn: title","expectedOutput":null,"kind":"bad","errors":["E08160"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08160/good.ek9","url":"https://ek9.io/errors/E08160.html","title":"Only an abstract component is injected","code":"#!ek9\ndefines module error.e08160.good\n\n  defines component\n\n    Timekeeper as abstract\n      now() as pure abstract\n        <- rtn as String?\n\n  defines function\n\n    report()\n      <- rtn as String?\n      timekeeper as Timekeeper!\n      rtn: timekeeper.now()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08160"}
{"id":"errors/E08170/bad.ek9","url":"https://ek9.io/errors/E08170.html","title":"E08170: an injected component is never assigned, not even with ':=?' - for a fallback, assign to a new variable ('chosen <- supplied' then 'chosen :=? injected')","code":"#!ek9\ndefines module error.e08170.bad\n\n  defines component\n\n    Timekeeper as abstract\n      now() as pure abstract\n        <- rtn as String?\n\n    NoonKeeper is Timekeeper\n      override now() as pure\n        <- rtn as String: \"noon\"\n\n  defines function\n\n    report()\n      <- rtn as String?\n      timekeeper as Timekeeper!\n      timekeeper :=? NoonKeeper()\n      rtn: timekeeper.now()","expectedOutput":null,"kind":"bad","errors":["E08170"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08170/good.ek9","url":"https://ek9.io/errors/E08170.html","title":"For a fallback, assign to a new variable","code":"#!ek9\ndefines module error.e08170.good\n\n  defines component\n\n    Timekeeper as abstract\n      now() as pure abstract\n        <- rtn as String?\n\n  defines function\n\n    report()\n      -> supplied as Timekeeper\n      <- rtn as String?\n      timekeeper as Timekeeper!\n      chosen <- supplied\n      chosen :=? timekeeper\n      rtn: chosen.now()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08170"}
{"id":"errors/E08180/bad.ek9","url":"https://ek9.io/errors/E08180.html","title":"E08180: not marked for injection nor initialised","code":"#!ek9\ndefines module error.e08180.bad\n\n  defines record\n\n    Book\n      title as String\n\n      default operator ?\n\n  defines function\n\n    greet()\n      <- rtn as String?\n      name as String\n      rtn: \"Hello \" + name","expectedOutput":null,"kind":"bad","errors":["E08180"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08180/good.ek9","url":"https://ek9.io/errors/E08180.html","title":"Initialise it, or say it may be unset with ?","code":"#!ek9\ndefines module error.e08180.good\n\n  defines record\n\n    Book\n      title as String: \"untitled\"\n\n      default operator ?\n\n  defines function\n\n    greet()\n      <- rtn as String?\n      name <- \"Steve\"\n      rtn: \"Hello \" + name\n\n    greetLater()\n      -> known as Boolean\n      <- rtn as String: \"Hello\"\n      name as String?\n      if known\n        name: \"Steve\"\n      else\n        name: \"friend\"\n      rtn: `${rtn} ${name}`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08180"}
{"id":"errors/E08190/bad.ek9","url":"https://ek9.io/errors/E08190.html","title":"E08190: circular dependency detected in component injection chain","code":"#!ek9\ndefines module error.e08190.bad\n\n  defines component\n\n    Orders as abstract\n      place() as abstract\n\n    Billing as abstract\n      charge() as abstract\n\n    OrderService is Orders\n      billing as Billing!\n      override place()\n        billing.charge()\n      default operator ?\n\n    BillingService is Billing\n      orders as Orders!\n      override charge()\n        orders.place()\n      default operator ?\n\n  defines application\n\n    shopApp\n      register OrderService() as Orders\n      register BillingService() as Billing\n\n  defines program\n\n    Shop() with application of shopApp\n      orders as Orders!\n      orders.place()","expectedOutput":null,"kind":"bad","errors":["E08190"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08190/good.ek9","url":"https://ek9.io/errors/E08190.html","title":"Break the cycle: Billing needs nothing from Orders, so it is registered first","code":"#!ek9\ndefines module error.e08190.good\n\n  defines component\n\n    Orders as abstract\n      place() as abstract\n\n    Billing as abstract\n      charge() as abstract\n\n    OrderService is Orders\n      billing as Billing!\n      override place()\n        billing.charge()\n      default operator ?\n\n    BillingService is Billing\n      override charge()\n        Stdout().println(\"charged\")\n\n  defines application\n\n    shopApp\n      register BillingService() as Billing\n      register OrderService() as Orders\n\n  defines program\n\n    Shop() with application of shopApp\n      orders as Orders!\n      orders.place()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08190"}
{"id":"errors/E08200/bad.ek9","url":"https://ek9.io/errors/E08200.html","title":"E08200: component used before registration in application block","code":"#!ek9\ndefines module error.e08200.bad\n\n  defines component\n\n    AbstractA as abstract\n      doWorkA() as abstract\n        <- rtn as Boolean?\n\n      default operator ?\n\n    AbstractB as abstract\n      doWorkB() as abstract\n        <- rtn as Boolean?\n\n      default operator ?\n\n    ComponentA is AbstractA\n\n      override doWorkA()\n        <- rtn as Boolean: true\n\n      default operator ?\n\n    ComponentB is AbstractB\n      svcA as AbstractA!\n\n      override doWorkB()\n        <- rtn as Boolean: true\n\n      default operator ?\n\n  defines application\n\n    orderingApp\n      register ComponentB() as AbstractB\n      register ComponentA() as AbstractA","expectedOutput":null,"kind":"bad","errors":["E08200"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08200/good.ek9","url":"https://ek9.io/errors/E08200.html","title":"Register what a component needs before the component","code":"#!ek9\ndefines module error.e08200.good\n\n  defines component\n\n    AbstractA as abstract\n      doWorkA() as abstract\n        <- rtn as Boolean?\n      default operator ?\n\n    AbstractB as abstract\n      doWorkB() as abstract\n        <- rtn as Boolean?\n      default operator ?\n\n    ComponentA is AbstractA\n      override doWorkA()\n        <- rtn as Boolean: true\n      default operator ?\n\n    ComponentB is AbstractB\n      svcA as AbstractA!\n      override doWorkB()\n        <- rtn as Boolean: svcA.doWorkA()\n      default operator ?\n\n  defines application\n\n    orderingApp\n      register ComponentA() as AbstractA\n      register ComponentB() as AbstractB","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08200"}
{"id":"errors/E08210/bad.ek9","url":"https://ek9.io/errors/E08210.html","title":"E08210: program uses injection but application has no registration for the required component type","code":"#!ek9\ndefines module error.e08210.bad\n\n  defines component\n\n    AbstractA as abstract\n      doWorkA() as abstract\n        <- rtn as Boolean?\n\n      default operator ?\n\n    AbstractB as abstract\n      doWorkB() as abstract\n        <- rtn as Boolean?\n\n      default operator ?\n\n    ComponentA is AbstractA\n      svcB as AbstractB!\n\n      override doWorkA()\n        <- rtn as Boolean: true\n\n      default operator ?\n\n  defines application\n\n    missingApp\n      register ComponentA() as AbstractA","expectedOutput":null,"kind":"bad","errors":["E08210"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08210/good.ek9","url":"https://ek9.io/errors/E08210.html","title":"Register every component that is injected","code":"#!ek9\ndefines module error.e08210.good\n\n  defines component\n\n    AbstractA as abstract\n      doWorkA() as abstract\n        <- rtn as Boolean?\n      default operator ?\n\n    AbstractB as abstract\n      doWorkB() as abstract\n        <- rtn as Boolean?\n      default operator ?\n\n    ComponentB is AbstractB\n      override doWorkB()\n        <- rtn as Boolean: true\n      default operator ?\n\n    ComponentA is AbstractA\n      svcB as AbstractB!\n      override doWorkA()\n        <- rtn as Boolean: svcB.doWorkB()\n      default operator ?\n\n  defines application\n\n    completeApp\n      register ComponentB() as AbstractB\n      register ComponentA() as AbstractA","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08210"}
{"id":"errors/E08220/bad.ek9","url":"https://ek9.io/errors/E08220.html","title":"E08220: program uses injection but has no linked application","code":"#!ek9\ndefines module error.e08220.bad\n\n  defines component\n\n    AbstractService as abstract\n      doWork() as abstract\n        <- rtn as Boolean?\n\n      default operator ?\n\n    ConcreteService is AbstractService\n      override doWork()\n        <- rtn as Boolean: true\n\n      default operator ?\n\n  defines program\n\n    noAppProgram()\n      stdout <- Stdout()\n\n      svc as AbstractService!\n      if svc.doWork()\n        stdout.println(\"test\")","expectedOutput":null,"kind":"bad","errors":["E08220"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08220/good.ek9","url":"https://ek9.io/errors/E08220.html","title":"Link the program to an application that registers the component","code":"#!ek9\ndefines module error.e08220.good\n\n  defines component\n\n    AbstractService as abstract\n      doWork() as abstract\n        <- rtn as Boolean?\n      default operator ?\n\n    ConcreteService is AbstractService\n      override doWork()\n        <- rtn as Boolean: true\n      default operator ?\n\n  defines application\n\n    serviceApp\n      register ConcreteService() as AbstractService\n\n  defines program\n\n    appProgram() with application of serviceApp\n      stdout <- Stdout()\n      svc as AbstractService!\n      if svc.doWork()\n        stdout.println(\"test\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08220"}
{"id":"errors/E08230/bad.ek9","url":"https://ek9.io/errors/E08230.html","title":"E08230: duplicate registration of the same abstract component type in application","code":"#!ek9\ndefines module error.e08230.bad\n\n  defines component\n\n    AbstractService as abstract\n      doWork() as abstract\n        <- rtn as Boolean?\n\n      default operator ?\n\n    ServiceImplA is AbstractService\n      override doWork()\n        <- rtn as Boolean: true\n\n      default operator ?\n\n    ServiceImplB is AbstractService\n      override doWork()\n        <- rtn as Boolean: false\n\n      default operator ?\n\n  defines application\n\n    dupApp\n      register ServiceImplA() as AbstractService\n      register ServiceImplB() as AbstractService","expectedOutput":null,"kind":"bad","errors":["E08230"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08230/good.ek9","url":"https://ek9.io/errors/E08230.html","title":"One registration per abstract component","code":"#!ek9\ndefines module error.e08230.good\n\n  defines component\n\n    AbstractService as abstract\n      doWork() as abstract\n        <- rtn as Boolean?\n      default operator ?\n\n    ServiceImplA is AbstractService\n      override doWork()\n        <- rtn as Boolean: true\n      default operator ?\n\n    ServiceImplB is AbstractService\n      override doWork()\n        <- rtn as Boolean: false\n      default operator ?\n\n  defines application\n\n    appA\n      register ServiceImplA() as AbstractService\n\n    appB\n      register ServiceImplB() as AbstractService","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08230"}
{"id":"errors/E08240/bad.ek9","url":"https://ek9.io/errors/E08240.html","title":"E08240: mutation operators are not applicable to function types, only '?' operator is supported","code":"#!ek9\ndefines module error.e08240.bad\n\n  defines function\n\n    Processor() as abstract\n      -> text as String\n      <- rtn as String?\n\n  defines class\n\n    TextHandler\n      processor as Processor?\n\n      default private TextHandler()\n\n      TextHandler()\n        -> handler as Processor\n        processor :=: handler\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E08240"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08240/good.ek9","url":"https://ek9.io/errors/E08240.html","title":"Assign the function; only ? applies to it","code":"#!ek9\ndefines module error.e08240.good\n\n  defines function\n\n    Processor() as abstract\n      -> text as String\n      <- rtn as String?\n\n  defines class\n\n    TextHandler\n      processor as Processor?\n\n      default private TextHandler()\n\n      TextHandler()\n        -> handler as Processor\n        processor: handler\n\n      isReady()\n        <- rtn as Boolean: processor?\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08240"}
{"id":"errors/E08250/bad.ek9","url":"https://ek9.io/errors/E08250.html","title":"E08250: 'this' cannot be passed as an argument to, or stored into, another object inside a constructor body","code":"#!ek9\ndefines module error.e08250.bad\n\n  defines class\n\n    Registry\n      items as List of Publisher: List() of Publisher\n\n      default Registry()\n\n      register()\n        -> p as Publisher\n        items += p\n\n      default operator ?\n\n    Publisher\n      name as String?\n\n      Publisher()\n        ->\n          n as String\n          reg as Registry\n        this.name: n\n\n        reg.register(this)\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E08250"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08250/good.ek9","url":"https://ek9.io/errors/E08250.html","title":"Construct the object first, then hand it on","code":"#!ek9\ndefines module error.e08250.good\n\n  defines class\n\n    Registry\n      items as List of Publisher: List() of Publisher\n\n      default Registry()\n\n      register()\n        -> publisher as Publisher\n        items += publisher\n\n      count()\n        <- rtn as Integer: length items\n\n      default operator ?\n\n    Publisher\n      name as String?\n\n      default private Publisher()\n\n      Publisher()\n        -> label as String\n        name: label\n\n      default operator ?\n\n  defines function\n\n    publishAll()\n      -> registry as Registry\n      <- rtn as Integer?\n      publisher <- Publisher(\"news\")\n      registry.register(publisher)\n      rtn: registry.count()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08250"}
{"id":"errors/E08250/good_consumer.ek9","url":"https://ek9.io/errors/E08250.html","title":"Or give this to a pure Consumer, which cannot keep it","code":"#!ek9\ndefines module error.e08250.good.consumer\n\n  defines record\n\n    ConfigurationDetails\n      host as String: \"localhost\"\n      port as Integer: 8080\n\n      default ConfigurationDetails() as pure\n\n      ConfigurationDetails() as pure\n        -> initializer as Consumer of ConfigurationDetails\n        initializer(this)\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08250"}
{"id":"errors/E08251/bad.ek9","url":"https://ek9.io/errors/E08251.html","title":"E08251: mutation of shared state must happen inside MutexLock.enter(...) — wrap the write in a MutexKey body","code":"#!ek9\ndefines module error.e08251.bad\n\n  defines component\n\n    Counter as abstract\n      bump() as abstract\n      default operator ?\n\n    UnsafeCounter extends Counter\n      count <- 0\n\n      override bump()\n        count: count + 1\n\n      default operator ?\n\n  defines service\n\n    Counters for :/counters open\n\n      countRequests() as GET for :/count\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"ok\")\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          default operator ?\n\n        counter as Counter!\n        counter.bump()\n\n  defines application\n\n    CounterApp\n      register UnsafeCounter() as Counter\n      register Counters()","expectedOutput":null,"kind":"bad","errors":["E08251"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08251/good.ek9","url":"https://ek9.io/errors/E08251.html","title":"Hold the shared state in a MutexLock and change it inside a MutexKey","code":"#!ek9\ndefines module error.e08251.good\n\n  defines component\n\n    Counter as abstract\n      bump() as abstract\n      default operator ?\n\n    SafeCounter extends Counter\n      count as MutexLock of Integer: MutexLock(Integer(0))\n\n      override bump()\n        bumper <- () is MutexKey of Integer as function\n          lockedItem++\n        require count.enter(bumper)\n\n      default operator ?\n\n  defines service\n\n    Counters for :/counters open\n\n      countRequests() as GET for :/count\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"ok\")\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          default operator ?\n        counter as Counter!\n        counter.bump()\n\n  defines application\n\n    CounterApp\n      register SafeCounter() as Counter\n      register Counters()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08251"}
{"id":"errors/E08252/bad.ek9","url":"https://ek9.io/errors/E08252.html","title":"E08252: nested enter() on a different lock identity — potential deadlock from lock-order cycle","code":"#!ek9\ndefines module error.e08252.bad\n\n  defines function\n\n    transferAtoB()\n      ->\n        lockA as MutexLock of Integer\n        lockB as MutexLock of String\n\n      innerKeyB <- () is MutexKey of String as function\n        stdout <- Stdout()\n        stdout.println(lockedItem)\n\n      outerKeyA <- (lockB, innerKeyB) is MutexKey of Integer as function\n        require lockB.enter(innerKeyB)\n\n      require lockA.enter(outerKeyA)\n\n    transferBtoA()\n      ->\n        lockA as MutexLock of Integer\n        lockB as MutexLock of String\n\n      innerKeyA <- () is MutexKey of Integer as function\n        stdout <- Stdout()\n        stdout.println(lockedItem)\n\n      outerKeyB <- (lockA, innerKeyA) is MutexKey of String as function\n        require lockA.enter(innerKeyA)\n\n      require lockB.enter(outerKeyB)","expectedOutput":null,"kind":"bad","errors":["E08252"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08252/good.ek9","url":"https://ek9.io/errors/E08252.html","title":"Protect the state that changes together under ONE lock","code":"#!ek9\ndefines module error.e08252.good\n\n  defines record\n\n    AccountPair\n      source as Integer: 0\n      target as Integer: 0\n\n      default operator ?\n\n  defines class\n\n    Ledger\n      accountLock as MutexLock of AccountPair: MutexLock(AccountPair())\n\n      transfer()\n        -> amount as Integer\n        key <- (amount) is MutexKey of AccountPair as function\n          lockedItem.source: lockedItem.source - amount\n          lockedItem.target: lockedItem.target + amount\n        require accountLock.enter(key)\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08252"}
{"id":"errors/E08253/bad.ek9","url":"https://ek9.io/errors/E08253.html","title":"E08253: same lock acquired across a thread boundary — inner acquire blocks waiting for outer holder; MutexLock reentrancy does not cross threads","code":"#!ek9\ndefines module error.e08253.bad\n\n  defines function\n\n    spawnHandlerOnSameLock()\n      -> theLock as MutexLock of Integer\n\n      handler <- (theLock) is SignalHandler as function\n        result: 0\n        innerKey <- () is MutexKey of Integer as function\n          stdout <- Stdout()\n          stdout.println(lockedItem)\n\n        require theLock.enter(innerKey)\n\n      signals <- Signals()\n      signals.register(\"SIGHUP\", handler)\n\n    crossThreadCaller()\n      -> theLock as MutexLock of Integer\n\n      outerKey <- (theLock) is MutexKey of Integer as function\n        spawnHandlerOnSameLock(theLock)\n\n      require theLock.enter(outerKey)","expectedOutput":null,"kind":"bad","errors":["E08253"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08253/good.ek9","url":"https://ek9.io/errors/E08253.html","title":"Do not hold the lock while starting work that takes it on another thread","code":"#!ek9\ndefines module error.e08253.good\n\n  defines function\n\n    spawnHandlerOnSameLock()\n      -> theLock as MutexLock of Integer\n      handler <- (theLock) is SignalHandler as function\n        result: 0\n        innerKey <- () is MutexKey of Integer as function\n          stdout <- Stdout()\n          stdout.println(lockedItem)\n        require theLock.enter(innerKey)\n      signals <- Signals()\n      signals.register(\"SIGHUP\", handler)\n\n    caller()\n      -> theLock as MutexLock of Integer\n      spawnHandlerOnSameLock(theLock)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08253"}
{"id":"errors/E08254/bad.ek9","url":"https://ek9.io/errors/E08254.html","title":"E08254: MutexLock cannot appear in a generic type parameter — move the lock to a class or component field","code":"#!ek9\ndefines module error.e08254.bad\n\n  defines function\n\n    badListOfLocks()\n      locks <- List() of MutexLock of String\n      require locks?\n\n    badOptionalLock()\n      maybeLock <- Optional() of MutexLock of Integer\n      require maybeLock?","expectedOutput":null,"kind":"bad","errors":["E08254"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08254/good.ek9","url":"https://ek9.io/errors/E08254.html","title":"Hold each lock in a field of a type, and collect that type","code":"#!ek9\ndefines module error.e08254.good\n\n  defines class\n\n    LockableText\n      text as MutexLock of String: MutexLock(\"\")\n\n      default operator ?\n\n  defines function\n\n    listOfLockables()\n      <- rtn as List of LockableText: [LockableText(), LockableText()]","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08254"}
{"id":"errors/E08255/bad.ek9","url":"https://ek9.io/errors/E08255.html","title":"E08255: two locks of the same type are nested but no consistent acquisition order can be statically proven — under some interleaving this will deadlock; protect the state under ONE lock over an owning record (and if the state is durable or shared across instances, a mutex cannot protect it — that is a transaction concern)","code":"#!ek9\ndefines module error.e08255.bad\n\n  defines class\n\n    Account\n      balanceLock as MutexLock of Integer: MutexLock(Integer(0))\n\n      getLock() as pure\n        <- rtn as MutexLock of Integer: balanceLock\n\n      default operator ?\n\n  defines function\n\n    transfer()\n      ->\n        from as Account\n        to as Account\n\n      innerKey <- () is MutexKey of Integer as function\n        stdout <- Stdout()\n        stdout.println(lockedItem)\n\n      outerKey <- (to, innerKey) is MutexKey of Integer as function\n        require to.getLock().enter(innerKey)\n\n      require from.getLock().enter(outerKey)","expectedOutput":null,"kind":"bad","errors":["E08255"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08255/good.ek9","url":"https://ek9.io/errors/E08255.html","title":"Keep both balances under one lock over an owning record","code":"#!ek9\ndefines module error.e08255.good\n\n  defines record\n\n    AccountPair\n      source as Integer: 0\n      target as Integer: 0\n\n      default operator ?\n\n  defines class\n\n    Ledger\n      accountLock as MutexLock of AccountPair: MutexLock(AccountPair())\n\n      transfer()\n        -> amount as Integer\n        key <- (amount) is MutexKey of AccountPair as function\n          lockedItem.source: lockedItem.source - amount\n          lockedItem.target: lockedItem.target + amount\n        require accountLock.enter(key)\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08255"}
{"id":"errors/E08256/bad.ek9","url":"https://ek9.io/errors/E08256.html","title":"E08256: MutexLock construction is only allowed as a field initialiser on a class or component","code":"#!ek9\ndefines module error.e08256.bad\n\n  defines function\n\n    //Local MutexLock inside a function body — rejected.\n    badLocalLock()\n      lock <- MutexLock(\"Steve\")\n      require lock?\n\n    //Returning a freshly-constructed MutexLock — rejected, because the\n    //construction site is inside the function body, not a field initialiser.\n    badReturningLock()\n      <- rtn as MutexLock of String: MutexLock(\"Stephen\")","expectedOutput":null,"kind":"bad","errors":["E08256"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08256/good.ek9","url":"https://ek9.io/errors/E08256.html","title":"Construct a MutexLock only as a field initialiser of a class or component","code":"#!ek9\ndefines module error.e08256.good\n\n  defines class\n\n    NameHolder\n      name as MutexLock of String: MutexLock(\"Steve\")\n\n      rename()\n        -> newName as String\n        key <- (newName) is MutexKey of String as function\n          lockedItem :=: newName\n        require name.enter(key)\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08256"}
{"id":"errors/E08257/bad.ek9","url":"https://ek9.io/errors/E08257.html","title":"E08257: MutexLock(...) argument must be a fresh value — a literal or a constructor call (copy existing state with a constructor: MutexLock(List(existing))); not a reference to existing state","code":"#!ek9\ndefines module error.e08257.bad\n\n  defines class\n\n    BadLeakedRef\n      stash as String: String(\"retained-by-caller\")\n\n      //Bad: 'stash' is retained by this class as a field; the MutexLock's\n      //payload is therefore aliased outside the lock.\n      lockedName as MutexLock of String: MutexLock(stash)\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E08257"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08257/good.ek9","url":"https://ek9.io/errors/E08257.html","title":"Give the lock a fresh value - a literal or a constructor call (a copy)","code":"#!ek9\ndefines module error.e08257.good\n\n  defines class\n\n    GoodFreshCopy\n      stash as String: String(\"retained-by-caller\")\n      lockedName as MutexLock of String: MutexLock(String(stash))\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08257"}
{"id":"errors/E08258/bad.ek9","url":"https://ek9.io/errors/E08258.html","title":"E08258: data inside a MutexLock must be purely contained — assigning 'lockedItem' creates an external reference; use ':=:' (copy), ':~:' (merge), or ':^:' (replace) instead","code":"#!ek9\ndefines module error.e08258.bad\n\n  defines class\n\n    LeakingHolder\n      lockedName as MutexLock of String: MutexLock(\"initial\")\n\n      //After this method returns, 'escaped' holds a reference to the same\n      //String object that lives inside lockedName — outside the lock.\n      expose()\n        <- escaped as String: String()\n\n        accessKey <- (escaped) is MutexKey of String as function\n          escaped := lockedItem\n\n        require lockedName.enter(accessKey)\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E08258"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08258/good.ek9","url":"https://ek9.io/errors/E08258.html","title":"Copy the locked value out with :=:","code":"#!ek9\ndefines module error.e08258.good\n\n  defines class\n\n    CopyingHolder\n      lockedName as MutexLock of String: MutexLock(\"initial\")\n\n      reveal()\n        <- copied as String: String()\n        accessKey <- (copied) is MutexKey of String as function\n          copied :=: lockedItem\n        require lockedName.enter(accessKey)\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08258"}
{"id":"errors/E08260/bad.ek9","url":"https://ek9.io/errors/E08260.html","title":"E08260: compile-time constant value violates the type's constraint — this would Panic at runtime","code":"#!ek9\ndefines module error.e08260.bad\n\n  defines type\n\n    Age as Integer constrain as\n      >= 16 and <= 100\n\n  defines program\n\n    AgeCheck()\n      stdout <- Stdout()\n      tooYoung <- Age(15)\n      stdout.println($tooYoung)","expectedOutput":null,"kind":"bad","errors":["E08260"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08260/good.ek9","url":"https://ek9.io/errors/E08260.html","title":"Construct a value the constraint admits","code":"#!ek9\ndefines module error.e08260.good\n\n  defines type\n\n    Age as Integer constrain as\n      >= 16 and <= 100\n\n  defines program\n\n    AgeCheck()\n      stdout <- Stdout()\n      youngest <- Age(16)\n      stdout.println($youngest)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08260"}
{"id":"errors/E08260/good_checked.ek9","url":"https://ek9.io/errors/E08260.html","title":"Or check a value only known at run time with of()","code":"#!ek9\ndefines module error.e08260.good.checked\n\n  defines type\n\n    Age as Integer constrain as\n      >= 16 and <= 100\n\n  defines program\n\n    AgeCheck()\n      -> rawInput as Integer\n      stdout <- Stdout()\n      if validAge <- Age().of(rawInput)\n        stdout.println($validAge)\n      else\n        stdout.println(\"rejected: out of range\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08260"}
{"id":"errors/E08261/bad.ek9","url":"https://ek9.io/errors/E08261.html","title":"E08261: no value of the base type can satisfy this constraint — every construction would Panic","code":"#!ek9\ndefines module error.e08261.bad\n\n  defines type\n\n    Digit as Integer constrain as\n      > 0 and < 1\n\n    Bracket as Integer constrain as\n      >= 10 and <= 5\n\n    Answer as Integer constrain as\n      == 42 and > 100","expectedOutput":null,"kind":"bad","errors":["E08261"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08261/good.ek9","url":"https://ek9.io/errors/E08261.html","title":"Write a constraint that some value satisfies","code":"#!ek9\ndefines module error.e08261.good\n\n  defines type\n\n    Digit as Integer constrain as\n      >= 0 and <= 9\n\n    Bracket as Integer constrain as\n      >= 5 and <= 10\n\n    Outlier as Integer constrain as\n      <= 10 or >= 90\n\n    Fraction as Float constrain as\n      > 0.0 and < 1.0","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08261"}
{"id":"errors/E08262/bad.ek9","url":"https://ek9.io/errors/E08262.html","title":"E08262: every suffixed value in a constraint must carry the SAME suffix — comparing across currencies or units is never satisfied","code":"#!ek9\ndefines module error.e08262.bad\n\n  defines type\n\n    Budget as Money constrain as\n      > 330#GBP and < 450#USD\n\n    Width as Dimension constrain as\n      >= 500mm and <= 90cm","expectedOutput":null,"kind":"bad","errors":["E08262"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08262/good.ek9","url":"https://ek9.io/errors/E08262.html","title":"Write every bound with the same suffix","code":"#!ek9\ndefines module error.e08262.good\n\n  defines type\n\n    Budget as Money constrain as\n      > 330#GBP and < 450#GBP\n\n    Width as Dimension constrain as\n      >= 500mm and <= 900mm","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08262"}
{"id":"errors/E08263/bad.ek9","url":"https://ek9.io/errors/E08263.html","title":"E08263: construction can never complete - every path through it constructs the same type again, so it overflows the stack at run time; construct the recursive part only under a condition, or hold it in an 'Optional of Type' or a 'List of Type', which start empty","code":"#!ek9\ndefines module error.e08263.bad\n\n  defines class\n\n    Node\n      next as Node: Node()\n\n      default Node() as pure\n\n      default operator ?\n\n    Pair\n      amount as Integer: 0\n\n      Pair()\n        -> initial as Integer\n        this($initial)\n\n      Pair()\n        -> text as String\n        this(length text)\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E08263"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08263/good.ek9","url":"https://ek9.io/errors/E08263.html","title":"Construct the recursive part only under a condition, or hold it unset until linked","code":"#!ek9\ndefines module error.e08263.good\n\n  defines class\n\n    Node\n      label as String: String()\n      next as Optional of Node: Optional() of Node\n\n      Node()\n        -> text as String\n        label: text\n\n      link()\n        -> node as Node\n        next: Optional(node)\n\n      override operator ? as pure\n        <- rtn as Boolean: label?\n\n    Tree\n      children as List of Tree: List() of Tree\n\n      Tree()\n        -> depth as Integer\n        if depth > 0\n          children += Tree(depth - 1)\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08263"}
{"id":"errors/E08264/bad.ek9","url":"https://ek9.io/errors/E08264.html","title":"E08264: this constructor leaves properties without a value - it can only be used through this() from a constructor that sets them; construct through a constructor that sets every property","code":"#!ek9\ndefines module error.e08264.bad\n\n  defines class\n\n    Label\n      text as String?\n\n      default private Label()\n\n      Label()\n        -> initial as String\n        this()\n        text: initial\n\n      blank()\n        <- rtn as Label: Label()\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E08264"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08264/good.ek9","url":"https://ek9.io/errors/E08264.html","title":"Construct through a constructor that sets every property","code":"#!ek9\ndefines module error.e08264.good\n\n  defines class\n\n    Label\n      text as String?\n\n      default private Label()\n\n      Label()\n        -> initial as String\n        text: initial\n\n      blank()\n        <- rtn as Label: Label(\"\")\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08264"}
{"id":"errors/E08265/bad.ek9","url":"https://ek9.io/errors/E08265.html","title":"E08265: a constraint's literal must match the operator's parameter type exactly — a constraint is never converted, so write the literal in that type or add the operator taking this one","code":"#!ek9\ndefines module error.e08265.bad\n\n  defines record\n\n    //A user-defined base whose comparison operators take a Float, not an Integer.\n    Price\n      amount as Float?\n\n      Price()\n        amount: Float()\n\n      Price()\n        -> initial as Float\n        amount: initial\n\n      Price()\n        -> other as Price\n        amount: other.amount\n\n      operator >= as pure\n        -> limit as Float\n        <- rtn as Boolean: amount >= limit\n\n      operator <= as pure\n        -> limit as Float\n        <- rtn as Boolean: amount <= limit\n\n      override operator ? as pure\n        <- rtn as Boolean: amount?\n\n      operator :=:\n        -> other as Price\n        amount :=: other.amount\n\n  defines type\n\n    //Built-in base: Float's '>=' takes a Float, so the Integer literal must be written 1.0.\n    Ratio as Float constrain as\n      >= 1 and <= 100\n\n    //The same constraint written in the operator's own type is fine - the false-positive guard.\n    GoodRatio as Float constrain as\n      >= 1.0 and <= 100.0\n\n    //User-defined base: either add 'operator >= as pure -> limit as Integer' to Price, or write 1.0.\n    Bounded as Price constrain as\n      >= 1 and <= 100.0\n\n    //Not just Float: a Character does not silently become a String either - write \"x\".\n    NotInitial as String constrain as\n      <> 'x'","expectedOutput":null,"kind":"bad","errors":["E08265"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08265/good.ek9","url":"https://ek9.io/errors/E08265.html","title":"Write each literal in the type the operator takes","code":"#!ek9\ndefines module error.e08265.good\n\n  defines type\n\n    Ratio as Float constrain as\n      >= 1.0 and <= 100.0\n\n    NotInitial as String constrain as\n      <> \"x\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08265"}
{"id":"errors/E08265/good_operator.ek9","url":"https://ek9.io/errors/E08265.html","title":"A user-defined base can instead ADD the operator that takes the literal's type","code":"#!ek9\ndefines module error.e08265.good.operator\n\n  defines record\n    Price\n      amount as Float?\n      Price()\n        amount: Float()\n      Price()\n        -> initial as Float\n        amount: initial\n      Price()\n        -> other as Price\n        amount: other.amount\n      operator >= as pure\n        -> limit as Float\n        <- rtn as Boolean: amount >= limit\n      //Takes an Integer, so the constraint below may compare with '1'\n      operator >= as pure\n        -> threshold as Integer\n        <- rtn as Boolean: amount >= #^threshold\n      override operator ? as pure\n        <- rtn as Boolean: amount?\n      operator :=:\n        -> other as Price\n        amount :=: other.amount\n\n  defines type\n    Bounded as Price constrain as\n      >= 1","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08265"}
{"id":"errors/E08266/bad.ek9","url":"https://ek9.io/errors/E08266.html","title":"E08266: an injected component is always set, so checking that it is set is always true - use the injected value directly; for a fallback, use a new variable ('chosen <- supplied' then 'chosen :=? injected')","code":"#!ek9\ndefines module error.e08266.bad\n\n  defines component\n\n    Logger as abstract\n      log() as abstract\n        -> message as String\n\n  defines function\n\n    report()\n      logger as Logger!\n      if logger?\n        logger.log(\"report\")","expectedOutput":null,"kind":"bad","errors":["E08266"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08266/good.ek9","url":"https://ek9.io/errors/E08266.html","title":"Use the injected component directly - it is always set","code":"#!ek9\ndefines module error.e08266.good\n\n  defines component\n\n    Logger as abstract\n      log() as abstract\n        -> message as String\n\n  defines function\n\n    report()\n      logger as Logger!\n      logger.log(\"report\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08266"}
{"id":"errors/E08266/good_fallback.ek9","url":"https://ek9.io/errors/E08266.html","title":"For a fallback, start from the other value and fill in with :=?","code":"#!ek9\ndefines module error.e08266.good.fallback\n\n  defines component\n\n    Logger as abstract\n      log() as abstract\n        -> message as String\n\n  defines function\n\n    choose()\n      -> supplied as Logger\n      logger as Logger!\n      chosen <- supplied\n      chosen :=? logger\n      chosen.log(\"choose\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08266"}
{"id":"errors/E08269/bad.ek9","url":"https://ek9.io/errors/E08269.html","title":"E08269: a coalescing operator ('??', '?:', '<?', '<=?', '>?', '>=?') mixed with a different binary operator must be parenthesised - it binds tighter than arithmetic, comparison and logic, so write '(a + b) ?: c' or 'a + (b ?: c)' to say which is meant","code":"#!ek9\ndefines module error.e08269.bad\n\n  defines function\n\n    total()\n      ->\n        first as Integer\n        second as Integer\n        fallback as Integer\n      <- rtn as Integer?\n      rtn: first + second ?: fallback\n\n    mixedForms()\n      ->\n        first as Integer\n        second as Integer\n        fallback as Integer\n        limit as Integer\n        floor as Integer\n        ready as Boolean\n        other as Boolean\n      sum <- first + second ?: fallback          //'?:' inside '+'\n      fallenBack <- first ?: second + fallback   //also '?:' inside '+': (first ?: second) + fallback\n      same <- first == second ?: fallback\n      both <- ready ?: false and other\n      smallest <- first <? second + limit        //'+' takes '<?' as an operand\n      bounded <- first <? second >? floor        //two DIFFERENT coalescing operators\n      chosen <- first ?: second ?? fallback      //'?:' and '??' are different operators\n      combined <- first ?? second + fallback     //'??' binds tighter than '+' too\n      power <- first ?? second ^ 2               //'^' binds tighter than '??'","expectedOutput":null,"kind":"bad","errors":["E08269"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08269/good.ek9","url":"https://ek9.io/errors/E08269.html","title":"Parenthesise the operand you mean","code":"#!ek9\ndefines module error.e08269.good\n\n  defines function\n\n    total()\n      ->\n        first as Integer\n        second as Integer\n        fallback as Integer\n      <- rtn as Integer?\n      rtn: (first + second) ?: fallback","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08269"}
{"id":"errors/E08269/good_forms.ek9","url":"https://ek9.io/errors/E08269.html","title":"Parenthesise to say which applies first; a chain of the same operator reads one way only","code":"#!ek9\ndefines module error.e08269.good.forms\n\n  defines function\n\n    readings()\n      ->\n        first as Integer\n        second as Integer\n        third as Integer\n        fallback as Integer\n        floor as Integer\n      <- rtn as String?\n      //The sum, or the fallback when the sum is unset\n      wholeSum <- (first + second) ?: fallback\n      //First plus (second, or the fallback)\n      oneOperand <- first + (second ?: fallback)\n      //The SAME operator chained reads one way only\n      chosen <- first ?: second ?: fallback\n      nearest <- first ?? second ?? fallback\n      smallest <- first <? second <? third\n      bounded <- (first <? second) >? floor\n      rtn: `${wholeSum} ${oneOperand} ${chosen} ${nearest} ${smallest} ${bounded}`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08269"}
{"id":"errors/E08270/bad.ek9","url":"https://ek9.io/errors/E08270.html","title":"E08270: a '<-' guard's variable is always unset in the later 'else if' and 'else' blocks of its 'if' - they run because it was unset - so this read finds nothing; use it inside the guarded block, or assign it a new value first","code":"#!ek9\ndefines module error.e08270.bad\n\n  defines function\n\n    fetch()\n      <- rtn as Integer: Integer()\n\n    demo()\n      stdout <- Stdout()\n      if found <- fetch()\n        stdout.println(`found ${found}`)\n      else\n        stdout.println(`missing ${found}`)","expectedOutput":null,"kind":"bad","errors":["E08270"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08270/good.ek9","url":"https://ek9.io/errors/E08270.html","title":"Use the guard variable where it is set; give the else its own value","code":"#!ek9\ndefines module error.e08270.good\n\n  defines function\n\n    fetch()\n      <- rtn as Integer: Integer()\n\n    fallback()\n      <- rtn as Integer: 1\n\n    demo()\n      stdout <- Stdout()\n      if found <- fetch()\n        stdout.println(`found ${found}`)\n      else\n        found := fallback()\n        stdout.println(`fell back to ${found}`)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08270"}
{"id":"errors/E08271/bad.ek9","url":"https://ek9.io/errors/E08271.html","title":"E08271: a 'register' statement constructs what it registers - call a constructor of the component or service (and of each aspect), not a function, method or delegate","code":"#!ek9\ndefines module error.e08271.bad\n\n  defines component\n\n    Svc as abstract\n      name() as abstract\n        <- rtn as String?\n\n    SvcImpl is Svc\n      override name()\n        <- rtn as String: \"service\"\n\n    Other as abstract\n      tag() as abstract\n        <- rtn as String?\n\n    Labelled is Other\n      label as String?\n\n      Labelled()\n        svc as Svc!\n        label: svc.name()\n\n      override tag()\n        <- rtn as String: label\n\n      default operator ?\n\n  defines function\n\n    makeOther()\n      <- rtn as Other: Labelled()\n\n  defines application\n\n    App\n      register SvcImpl() as Svc\n      register makeOther() as Other","expectedOutput":null,"kind":"bad","errors":["E08271"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08271/good.ek9","url":"https://ek9.io/errors/E08271.html","title":"Register a constructor call of the component","code":"#!ek9\ndefines module error.e08271.good\n\n  defines component\n\n    Svc as abstract\n      name() as abstract\n        <- rtn as String?\n\n    SvcImpl is Svc\n      override name()\n        <- rtn as String: \"service\"\n\n    Other as abstract\n      tag() as abstract\n        <- rtn as String?\n\n    Labelled is Other\n      label as String?\n\n      Labelled()\n        svc as Svc!\n        label: svc.name()\n\n      override tag()\n        <- rtn as String: label\n\n      default operator ?\n\n  defines application\n\n    App\n      register SvcImpl() as Svc\n      register Labelled() as Other","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08271"}
{"id":"errors/E08272/bad.ek9","url":"https://ek9.io/errors/E08272.html","title":"E08272: a for-range creates new values of its declared type - its counter as T(start) and each loop variable as T(counter) - so the range type must be concrete and have a public copy constructor T(T) that produces an independent value","code":"#!ek9\ndefines module error.e08272.bad\n\n  defines class\n\n    Step\n      position as Integer?\n\n      default private Step() as pure\n\n      Step() as pure\n        -> initial as Integer\n        position :=? Integer(initial)\n\n      operator <=> as pure\n        -> other as Step\n        <- rtn as Integer: position <=> other.position\n\n      operator #? as pure\n        <- rtn as Integer: #? position\n\n      operator ++\n        position++\n\n      operator --\n        position--\n\n      operator $ as pure\n        <- rtn as String: $position\n\n      default operator ?\n\n  defines function\n\n    countSteps()\n      stdout <- Stdout()\n      for step in Step(1) ... Step(3)\n        stdout.println($step)","expectedOutput":null,"kind":"bad","errors":["E08272"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08272/good.ek9","url":"https://ek9.io/errors/E08272.html","title":"Give the type a public copy constructor T(T)","code":"#!ek9\ndefines module error.e08272.good\n\n  defines class\n\n    Step\n      position as Integer?\n\n      default private Step() as pure\n\n      Step() as pure\n        -> initial as Integer\n        position :=? Integer(initial)\n\n      Step() as pure\n        -> other as Step\n        position :=? Integer(other.position)\n\n      operator <=> as pure\n        -> other as Step\n        <- rtn as Integer: position <=> other.position\n\n      operator #? as pure\n        <- rtn as Integer: #? position\n\n      operator ++\n        position++\n\n      operator --\n        position--\n\n      operator $ as pure\n        <- rtn as String: $position\n\n      default operator ?\n\n  defines function\n\n    countSteps()\n      stdout <- Stdout()\n      for step in Step(1) ... Step(3)\n        stdout.println($step)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08272"}
{"id":"errors/E08273/bad.ek9","url":"https://ek9.io/errors/E08273.html","title":"E08273: word 'not' is never an operand of another operator unless parenthesised, except 'and', 'xor' and 'or' - it binds below the comparisons, so write 'a == (not b)' or '$ (not b)', or 'not (a == b)' if that is meant; 'a and not b' needs none","code":"#!ek9\ndefines module error.e08273.bad\n\n  defines function\n\n    sameAsNot()\n      ->\n        ready as Boolean\n        done as Boolean\n      <- rtn as Boolean?\n      rtn: ready == not done\n\n    otherForms()\n      ->\n        ready as Boolean\n        done as Boolean\n        low as Boolean\n        high as Boolean\n        flag as Boolean\n        other as Boolean\n        wanted as List of Boolean\n      same <- ready == not done\n      under <- low < not high\n      chosen <- flag ?: not other\n      found <- ready in not wanted\n      text <- $ not done                 //a prefix operator","expectedOutput":null,"kind":"bad","errors":["E08273"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08273/good.ek9","url":"https://ek9.io/errors/E08273.html","title":"Parenthesise the not - or the comparison, if that is what is meant","code":"#!ek9\ndefines module error.e08273.good\n\n  defines function\n\n    sameAsNot()\n      ->\n        ready as Boolean\n        done as Boolean\n      <- rtn as Boolean?\n      rtn: ready == (not done)\n\n    notSame()\n      ->\n        ready as Boolean\n        done as Boolean\n      <- rtn as Boolean?\n      rtn: not (ready == done)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08273"}
{"id":"errors/E08273/good_forms.ek9","url":"https://ek9.io/errors/E08273.html","title":"Parenthesise the negation, negate the whole comparison, or use 'and'/'or'","code":"#!ek9\ndefines module error.e08273.good.forms\n\n  defines function\n\n    readings()\n      ->\n        ready as Boolean\n        done as Boolean\n      <- rtn as String?\n      //Negate only the right operand\n      same <- ready == (not done)\n      //Negate the comparison (also written 'not ready == done')\n      different <- not (ready == done)\n      //'and', 'xor' and 'or' bind below 'not': one reading only\n      both <- ready and not done\n      either <- ready or not done\n      //A prefix operator over a parenthesised negation\n      text <- $ (not done)\n      //'~' is the tight negation: no parentheses needed\n      tight <- ready == ~done\n      rtn: `${same} ${different} ${both} ${either} ${text} ${tight}`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08273"}
{"id":"errors/E08274/bad.ek9","url":"https://ek9.io/errors/E08274.html","title":"E08274: a negation applied to a negation - word 'not', '~' or unary '-' in any mix, parenthesised or not ('not not b', 'not (not b)', '~~b', '- -x', '-(-x)') - cancels out: write the operand, or a single negation if one was meant","code":"#!ek9\ndefines module error.e08274.bad\n\n  defines function\n\n    stillDone()\n      -> done as Boolean\n      <- rtn as Boolean?\n      rtn: not not done\n\n    everySpelling()\n      ->\n        done as Boolean\n        amount as Integer\n      twice <- not not done              //this is 'done'\n      tilde <- ~~done\n      mixed <- not ~done\n      mixedAgain <- ~not done\n      minus <- - -amount                 //this is 'amount'\n      minusNot <- -not done\n      //Parentheses group; they do not change what is negated\n      grouped <- not (not done)\n      groupedTilde <- ~(~done)\n      groupedMinus <- -(-amount)","expectedOutput":null,"kind":"bad","errors":["E08274"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E08274/good.ek9","url":"https://ek9.io/errors/E08274.html","title":"Write the operand itself","code":"#!ek9\ndefines module error.e08274.good\n\n  defines function\n\n    stillDone()\n      -> done as Boolean\n      <- rtn as Boolean?\n      rtn: done","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08274"}
{"id":"errors/E08274/good_forms.ek9","url":"https://ek9.io/errors/E08274.html","title":"Write the operand, or exactly one negation; a negated subtraction is fine","code":"#!ek9\ndefines module error.e08274.good.forms\n\n  defines function\n\n    readings()\n      ->\n        done as Boolean\n        first as Integer\n        second as Integer\n      <- rtn as String?\n      //What the double negation meant\n      same <- done\n      //If a single negation was meant\n      flipped <- not done\n      //The tight spelling of the same thing\n      tight <- ~done\n      //A negation of a subtraction\n      opposite <- -(first - second)\n      rtn: `${same} ${flipped} ${tight} ${opposite}`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E08274"}
{"id":"errors/E09010/bad.ek9","url":"https://ek9.io/errors/E09010.html","title":"E09010: inappropriate use in this context","code":"#!ek9\ndefines module error.e09010.bad\n\n  defines class\n\n    Greeter\n      greet()\n        <- rtn as String: \"Hello\"\n\n  defines function\n\n    makeGreeter()\n      <- rtn as Greeter: Greeter","expectedOutput":null,"kind":"bad","errors":["E09010"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E09010/good.ek9","url":"https://ek9.io/errors/E09010.html","title":"Construct an instance - a type name alone is not a value","code":"#!ek9\ndefines module error.e09010.good\n\n  defines class\n\n    Greeter\n      greet()\n        <- rtn as String: \"Hello\"\n\n  defines function\n\n    makeGreeter()\n      <- rtn as Greeter: Greeter()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E09010"}
{"id":"errors/E10010/bad.ek9","url":"https://ek9.io/errors/E10010.html","title":"E10010: 'void' return type cannot be used with an assignment","code":"#!ek9\ndefines module error.e10010.bad\n\n  defines function\n\n    logItem()\n      -> item as String\n      stdout <- Stdout()\n      stdout.println(item)\n\n    process()\n      outcome <- logItem(\"first\")\n      require outcome?","expectedOutput":null,"kind":"bad","errors":["E10010"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E10010/good.ek9","url":"https://ek9.io/errors/E10010.html","title":"Call it as a statement, or give it a returning variable","code":"#!ek9\ndefines module error.e10010.good\n\n  defines function\n\n    logItem()\n      -> item as String\n      stdout <- Stdout()\n      stdout.println(item)\n\n    describe()\n      -> item as String\n      <- rtn as String: `item: ${item}`\n\n    process()\n      logItem(\"first\")\n      outcome <- describe(\"second\")\n      logItem(outcome)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E10010"}
{"id":"errors/E10011/bad.ek9","url":"https://ek9.io/errors/E10011.html","title":"E10011: 'Void' is the absence of a value - it cannot be the type of a variable, property, parameter or type argument","code":"#!ek9\ndefines module error.e10011.bad\n\n  defines trait\n\n    Processor\n      process() as abstract\n        -> nothing as Void\n\n  defines record\n\n    Holder\n      nothing as Void?\n\n      default operator ?\n\n  defines function\n\n    //VALID: no returning variable - this function returns Void\n    doNothing()\n      stdout <- Stdout()\n      stdout.println(\"nothing\")\n\n    voidParameter()\n      -> nothing as Void\n      stdout <- Stdout()\n      stdout.println(\"void parameter\")\n\n    voidReturningVariable() as abstract\n      <- nothing as Void?\n\n    voidLocalVariable()\n      nothing as Void?\n      stdout <- Stdout()\n      stdout.println(`${nothing?}`)\n\n    voidListParameter()\n      -> nothings as List of Void\n      stdout <- Stdout()\n      stdout.println(\"void list parameter\")\n\n    voidNestedListParameter()\n      -> nothings as List of List of Void\n      stdout <- Stdout()\n      stdout.println(\"void nested list parameter\")\n\n    voidListConstruction()\n      nothings <- List() of Void\n      stdout <- Stdout()\n      stdout.println($ length nothings)\n\n    voidDictConstruction()\n      nothings <- Dict() of (String, Void)\n      stdout <- Stdout()\n      stdout.println($ length nothings)\n\n    voidOptionalReturn() as abstract\n      <- nothing as Optional of Void?\n\n  defines class\n\n    Worker\n      work()\n        -> nothing as Void\n        doNothing()","expectedOutput":null,"kind":"bad","errors":["E10011"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E10011/good.ek9","url":"https://ek9.io/errors/E10011.html","title":"Leave out what has no value: a function with no returning variable already returns nothing","code":"#!ek9\ndefines module error.e10011.good\n\n  defines function\n\n    doNothing()\n      stdout <- Stdout()\n      stdout.println(\"nothing\")\n\n    messages()\n      <- rtn as List of String: List()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E10011"}
{"id":"errors/E10020/bad.ek9","url":"https://ek9.io/errors/E10020.html","title":"E10020: Void cannot be used in stream pipelines","code":"#!ek9\ndefines module error.e10020.bad\n\n  defines function\n    voidFunction()\n      -> item as String\n      require item?\n      //No return mainValue - returns Void\n\n    testStreamWithVoid()\n      values <- [\"a\", \"b\", \"c\"]\n      result <- cat values | map voidFunction | collect as Void","expectedOutput":null,"kind":"bad","errors":["E10020"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E10020/good.ek9","url":"https://ek9.io/errors/E10020.html","title":"Give each stage a function that returns a value","code":"#!ek9\ndefines module error.e10020.good\n\n  defines function\n\n    shout() as pure\n      -> item as String\n      <- rtn as String: item.upperCase()\n\n    testStream()\n      <- rtn as List of String: List()\n      values <- [\"a\", \"b\", \"c\"]\n      rtn: cat values | map shout | collect as List of String","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E10020"}
{"id":"errors/E10030/bad.ek9","url":"https://ek9.io/errors/E10030.html","title":"E10030: use of a constructor directly on an abstract type is not permitted.","code":"#!ek9\ndefines module error.e10030.bad\n\n  defines class\n\n    Shape as abstract\n      area() as abstract\n        <- rtn as Float?\n\n      default operator ?\n\n    Square extends Shape\n      side as Float?\n\n      default private Square()\n\n      Square()\n        -> sideLength as Float\n        side: sideLength\n\n      override area()\n        <- rtn as Float: side * side\n\n      default operator ?\n\n    <?-\n      The no-arg constructor is private and never called, but it calls T().\n    -?>\n    Holder of type T\n      item as T?\n\n      private Holder()\n        item: T()\n\n      Holder()\n        -> initial as T\n        item: initial\n\n      get()\n        <- rtn as T: item\n\n      default operator ?\n\n  defines function\n\n    <?-\n      Shape is abstract: parameterising Holder with it turns the private constructor's T() into Shape().\n    -?>\n    holdAbstract()\n      square as Shape: Square(3.0)\n      held <- Holder(square)\n      require held?","expectedOutput":null,"kind":"bad","errors":["E10030"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E10030/good.ek9","url":"https://ek9.io/errors/E10030.html","title":"Leave the T property unset in a private no-arg constructor - no T() is needed","code":"#!ek9\ndefines module error.e10030.good\n\n  defines class\n\n    Shape as abstract\n      area() as abstract\n        <- rtn as Float?\n      default operator ?\n\n    Square extends Shape\n      side as Float?\n\n      default private Square()\n\n      Square()\n        -> sideLength as Float\n        side: sideLength\n\n      override area()\n        <- rtn as Float: side * side\n\n      default operator ?\n\n    Holder of type T\n      item as T?\n\n      default private Holder()\n\n      Holder()\n        -> initial as T\n        item: initial\n\n      get()\n        <- rtn as T: item\n\n      default operator ?\n\n  defines function\n\n    holdAbstract()\n      <- rtn as Float?\n      square as Shape: Square(3.0)\n      held <- Holder(square)\n      rtn: held.get().area()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E10030"}
{"id":"errors/E10031/bad.ek9","url":"https://ek9.io/errors/E10031.html","title":"E10031: 'T()' in the generic type needs a public no-argument constructor on the type used to parameterise it","code":"#!ek9\ndefines module error.e10031.bad\n\n  defines class\n\n    PureHolder of type T\n      item as T?\n\n      PureHolder() as pure\n        item :=? T()\n\n      PureHolder() as pure\n        -> initial as T\n        item :=? initial\n\n      default operator ?\n\n    PrivateNoArgThing\n      content as String?\n\n      default private PrivateNoArgThing() as pure\n\n      PrivateNoArgThing() as pure\n        -> initial as String\n        content :=? initial\n\n      default operator ?\n\n  defines function\n\n    tryPrivateNoArg()\n      held <- PureHolder() of PrivateNoArgThing\n      require held?","expectedOutput":null,"kind":"bad","errors":["E10031"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E10031/good.ek9","url":"https://ek9.io/errors/E10031.html","title":"Give the type a public no-argument constructor for T()","code":"#!ek9\ndefines module error.e10031.good\n\n  defines class\n\n    PureHolder of type T\n      item as T?\n\n      PureHolder() as pure\n        item :=? T()\n\n      PureHolder() as pure\n        -> initial as T\n        item :=? initial\n\n      default operator ?\n\n    PublicNoArgThing\n      content as String?\n\n      PublicNoArgThing() as pure\n        content :=? \"default\"\n\n      PublicNoArgThing() as pure\n        -> initial as String\n        content :=? initial\n\n      default operator ?\n\n  defines function\n\n    tryPublicNoArg()\n      held <- PureHolder() of PublicNoArgThing\n      require held?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E10031"}
{"id":"errors/E10032/bad.ek9","url":"https://ek9.io/errors/E10032.html","title":"E10032: a constructor the generic uses on T from a pure scope ('T()', or the copy constructor 'T(T)' a for-range uses) must be pure on the type used to parameterise it","code":"#!ek9\ndefines module error.e10032.bad\n\n  defines class\n\n    PureHolder of type T\n      item as T?\n\n      PureHolder() as pure\n        item :=? T()\n\n      PureHolder() as pure\n        -> initial as T\n        item :=? initial\n\n      default operator ?\n\n    NonPureNoArgThing\n      content as String?\n\n      NonPureNoArgThing()\n        content :=? \"default\"\n\n      default operator ?\n\n  defines function\n\n    tryNonPureNoArg()\n      held <- PureHolder() of NonPureNoArgThing\n      require held?","expectedOutput":null,"kind":"bad","errors":["E10032"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E10032/good.ek9","url":"https://ek9.io/errors/E10032.html","title":"Mark the no-argument constructor pure","code":"#!ek9\ndefines module error.e10032.good\n\n  defines class\n\n    PureHolder of type T\n      item as T?\n\n      PureHolder() as pure\n        item :=? T()\n\n      PureHolder() as pure\n        -> initial as T\n        item :=? initial\n\n      default operator ?\n\n    PureNoArgThing\n      content as String?\n\n      PureNoArgThing() as pure\n        content :=? \"default\"\n\n      default operator ?\n\n  defines function\n\n    tryPureNoArg()\n      held <- PureHolder() of PureNoArgThing\n      require held?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E10032"}
{"id":"errors/E10040/bad.ek9","url":"https://ek9.io/errors/E10040.html","title":"E10040: 'group' requires a preceding 'sort' with no type-changing operations between them","code":"#!ek9\ndefines module error.e10040.bad\n\n  defines record\n\n    R1 as open\n      name as String?\n\n      default private R1()\n\n      R1()\n        -> text as String\n        this.name: text\n\n      //Equatable (not orderable) sameness; its '#?' goes with it.\n      default operator ==\n\n      default operator #?\n\n      default operator $\n\n      default operator ?\n\n    R2\n      label as String?\n\n      default private R2()\n\n      R2()\n        -> text as String\n        this.label: text\n\n      //Equatable (not orderable) sameness; its '#?' goes with it.\n      default operator ==\n\n      default operator #?\n\n      default operator $\n\n      default operator ?\n\n  defines function\n\n    <?-\n      Maps R1 to R2 - this is a type-changing function.\n    -?>\n    MapR1toR2()\n      -> item as R1\n      <- rtn as R2: R2($item)\n\n    <?-\n      Filter function that keeps items with non-empty names.\n    -?>\n    hasContent()\n      -> item as R1\n      <- rtn as Boolean: item?\n\n    comparingR1() as pure\n      ->\n        r1 as R1\n        r2 as R1\n      <- rtn as Integer: $r1 <=> $r2\n\n    comparingR2() as pure\n      ->\n        r1 as R2\n        r2 as R2\n      <- rtn as Integer: $r1 <=> $r2\n\n  defines function\n\n    <?-\n      Group without any sort - the simplest invalid case.\n    -?>\n    GroupWithNoSort()\n      collection <- List() of List of String\n\n      cat [\"A\", \"Z\", \"Z\", \"P\", \"B\"] | group > collection\n\n      require collection?\n\n    <?-\n      Sort followed by map changes the type, so the sort is invalidated.\n      The group sees R2 but the sort was on R1.\n    -?>\n    GroupAfterMapInvalidatesSort()\n      collection <- List() of List of R2\n\n      cat [R1(\"A\"), R1(\"Z\"), R1(\"P\")] | sort by comparingR1 | map with MapR1toR2 | group > collection\n\n      require collection?\n\n    <?-\n      First group changes type from T to List of T, invalidating the sort for a second group.\n    -?>\n    SecondGroupAfterFirstGroupInvalidatesSort()\n      collection <- List() of List of List of String\n\n      cat [\"A\", \"Z\", \"Z\", \"P\"] | sort | group | group > collection\n\n      require collection?\n\n    <?-\n      Filter is type-preserving, so sort remains valid through filter.\n      This should compile successfully.\n    -?>\n    GroupAfterFilterPreservesSort()\n      collection <- List() of List of R1\n\n      cat [R1(\"A\"), R1(\"Z\"), R1(\"P\")] | sort by comparingR1 | filter by hasContent | group > collection\n\n      require collection?\n\n    <?-\n      Valid: sort immediately before group.\n    -?>\n    GroupWithImmediateSort()\n      collection <- List() of List of String\n\n      cat [\"A\", \"Z\", \"Z\", \"P\", \"B\"] | sort | group > collection\n\n      require collection?\n\n    <?-\n      Valid: sort with comparator before group.\n    -?>\n    GroupWithSortByComparator()\n      collection <- List() of List of R1\n\n      cat [R1(\"A\"), R1(\"Z\"), R1(\"P\")] | sort by comparingR1 | group > collection\n\n      require collection?","expectedOutput":null,"kind":"bad","errors":["E10040"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E10040/good.ek9","url":"https://ek9.io/errors/E10040.html","title":"Sort immediately before group (a type-preserving filter between is fine)","code":"#!ek9\ndefines module error.e10040.good\n\n  defines function\n\n    groupSorted()\n      <- rtn as List of List of String: List()\n      rtn: cat [\"A\", \"Z\", \"Z\", \"P\", \"B\"] | sort | group | collect as List of List of String","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E10040"}
{"id":"errors/E10050/bad.ek9","url":"https://ek9.io/errors/E10050.html","title":"E10050: this operation needs a bounded source; an unbounded source (Stdin, UDP, TCPConnection) or an infinite one (an iterator whose hasNext() always returns true) must be bounded first with 'head N'","code":"#!ek9\ndefines module error.e10050.bad\n\n  defines program\n\n    SortInput()\n      stdin <- Stdin()\n      stdout <- Stdout()\n      cat stdin | sort > stdout","expectedOutput":null,"kind":"bad","errors":["E10050"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E10050/good.ek9","url":"https://ek9.io/errors/E10050.html","title":"Bound the source with head first","code":"#!ek9\ndefines module error.e10050.good\n\n  defines constant\n\n    MAX_LINES <- 1000\n\n  defines program\n\n    SortInput()\n      stdin <- Stdin()\n      stdout <- Stdout()\n      cat stdin | head MAX_LINES | sort > stdout","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E10050"}
{"id":"errors/E10050/good_streaming.ek9","url":"https://ek9.io/errors/E10050.html","title":"Streaming stages need no bound; 'head' bounds even a source that never ends","code":"#!ek9\ndefines module error.e10050.good.streaming\n\n  defines class\n    //hasNext() always answers true: the compiler proves this source never ends\n    Forever\n      count <- 0\n      hasNext() as pure\n        <- rtn as Boolean: true\n      next()\n        <- rtn as Integer: Integer(count)\n        count++\n      default operator ?\n\n  defines function\n    validLine() as pure\n      -> line as String\n      <- rtn as Boolean: not line.empty()\n\n    shout() as pure\n      -> line as String\n      <- rtn as String: line.upperCase()\n\n  defines program\n    EchoInput()\n      stdin <- Stdin()\n      stdout <- Stdout()\n      //Each item is processed as it arrives: no bound is needed\n      cat stdin | filter by validLine | map with shout > stdout\n\n    FirstTen()\n      stdout <- Stdout()\n      //'head' bounds the never-ending source before anything waits for its end\n      cat Forever() | head 10 | sort > stdout\n      firstTen <- cat Forever() | head 10 | collect as List of Integer\n      stdout.println($firstTen)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E10050"}
{"id":"errors/E11010/bad.ek9","url":"https://ek9.io/errors/E11010.html","title":"E11010: excessive complexity - refactor","code":"#!ek9\ndefines module error.e11010.bad\n\n  defines function\n\n    isPositive() as pure\n      -> item as Integer\n      <- rtn as Boolean: item > 0\n\n    isLarge() as pure\n      -> item as Integer\n      <- rtn as Boolean?\n      threshold <- 10\n      rtn: item > threshold\n\n    doubleIt() as pure\n      -> item as Integer\n      <- rtn as Integer: item * 2\n\n    addTen() as pure\n      -> item as Integer\n      <- rtn as Integer: item + 10\n\n    joiner() as pure\n      ->\n        a as Integer\n        b as Integer\n      <- rtn as Integer: a + b\n\n  defines function\n\n    <?-\n      Multiple complex pipelines with type-changing operations push the\n      function complexity over the EXCESSIVE_COMPLEXITY threshold of 45.\n\n      Pipeline 1: sort(1) + group(2) + flatten(2) + map(2) + tee(2) + filter(1) + head(1) = 11\n      Pipeline 2: filter(1) + map(2) + sort(1) + map(2) + skip(1) + head(1) = 8\n      Pipeline 3: sort(1) + filter(1) + map(2) + map(2) + tee(2) + uniq(1) = 9\n      Pipeline 4: filter(1) + sort(1) + join(2) = 4\n      Sources: 4 x cat(1) = 4, terminals: 4 x (1) = 4\n      Other: exit(1) + require(3) + if(2) + comparisons(4) = 10\n      Total: 11 + 8 + 9 + 4 + 4 + 4 + 10 = 50\n    -?>\n    BadStreamComplexity()\n      stdout <- Stdout()\n\n      sideCapture1 <- List() of Integer\n      sideCapture2 <- List() of Integer\n\n      //Pipeline 1: sort, group, flatten, map, tee, filter, head (7 stages, 11 weighted)\n      cat [8, 3, 5, 3, 8, 1, 5, 2, 1, 8]\n        | sort\n        | group\n        | flatten\n        | map by doubleIt\n        | tee in sideCapture1\n        | filter by isPositive\n        | head 3\n        > stdout\n\n      //Pipeline 2: filter, map, sort, map, skip, head (6 stages, 8 weighted)\n      cat [100, -50, 200, -75, 300, 25, -10, 150]\n        | filter by isPositive\n        | map by doubleIt\n        | sort\n        | map by addTen\n        | skip 1\n        | head 3\n        > stdout\n\n      //Pipeline 3: sort, filter, map, map, tee, uniq (6 stages, 9 weighted)\n      cat [5, 10, 15, 5, 20, 10, 25, 15, 30]\n        | sort\n        | filter by isLarge\n        | map by doubleIt\n        | map by addTen\n        | tee in sideCapture2\n        | uniq\n        > stdout\n\n      //Pipeline 4: filter, sort, join (3 stages, 4 weighted)\n      total <- cat [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n        | filter by isPositive\n        | sort\n        | join with joiner\n        | collect as Integer\n\n      //Pipeline 5: sort, group, flatten, map, filter, head (6 stages, 10 weighted)\n      cat [7, 2, 9, 2, 7, 4, 9, 1]\n        | sort\n        | group\n        | flatten\n        | map by addTen\n        | filter by isLarge\n        | head 5\n        > stdout\n\n      //Pipeline 6: filter, map, sort, map, uniq (5 stages, 7 weighted)\n      cat [11, 22, 33, 11, 44, 22, 55]\n        | filter by isPositive\n        | map by doubleIt\n        | sort\n        | map by addTen\n        | uniq\n        > stdout\n\n      //Pipeline 7: sort, group, flatten, map, tee, filter, map, uniq, head (9 stages, 16 weighted)\n      cat [3, 6, 9, 3, 12, 6, 15, 9, 18]\n        | sort\n        | group\n        | flatten\n        | map by doubleIt\n        | tee in sideCapture1\n        | filter by isPositive\n        | map by addTen\n        | uniq\n        | head 5\n        > stdout\n\n      require total?\n      require length sideCapture1 > 0\n      require length sideCapture2 > 0\n\n      if total > 0\n        stdout.println($total)\n      minCapture <- 2\n      if length sideCapture1 > minCapture\n        stdout.println(\"captured enough\")","expectedOutput":null,"kind":"bad","errors":["E11010"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11010/good.ek9","url":"https://ek9.io/errors/E11010.html","title":"Give each pipeline its own function","code":"#!ek9\ndefines module error.e11010.good\n\n  defines function\n\n    isPositive() as pure\n      -> item as Integer\n      <- rtn as Boolean: item > 0\n\n    doubleIt() as pure\n      -> item as Integer\n      <- rtn as Integer: item * 2\n\n    addTen() as pure\n      -> item as Integer\n      <- rtn as Integer: item + 10\n\n    firstThreeDoubled()\n      -> numbers as List of Integer\n      <- rtn as List of Integer: List()\n      rtn: cat numbers | sort | uniq | map by doubleIt | filter by isPositive | head 3 | collect as List of Integer\n\n    shiftedPositives()\n      -> numbers as List of Integer\n      <- rtn as List of Integer: List()\n      rtn: cat numbers | filter by isPositive | map by addTen | sort | collect as List of Integer\n\n  defines program\n\n    StreamsInParts()\n      stdout <- Stdout()\n      stdout.println($firstThreeDoubled([8, 3, 5, 3, 8, 1]))\n      stdout.println($shiftedPositives([100, -50, 200]))","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11010"}
{"id":"errors/E11011/bad.ek9","url":"https://ek9.io/errors/E11011.html","title":"E11011: excessive nesting - extract function","code":"#!ek9\ndefines module error.e11011.bad\n\n  defines function\n\n    deepSimpleNesting()\n      -> mainValue as Integer\n      <- result as Integer: 0\n\n      levelTwo <- 2\n      levelThree <- 3\n      levelFour <- 4\n      levelFive <- 5\n      levelSix <- 6\n\n      if mainValue > 0\n        if mainValue > 1\n          if mainValue > levelTwo\n            if mainValue > levelThree\n              if mainValue > levelFour\n                if mainValue > levelFive\n                  if mainValue > levelSix\n                    result: 7","expectedOutput":null,"kind":"bad","errors":["E11011"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11011/good.ek9","url":"https://ek9.io/errors/E11011.html","title":"Extract the inner levels into a function of their own","code":"#!ek9\ndefines module error.e11011.good\n\n  defines constant\n\n    LOW <- 3\n    HIGH <- 6\n\n  defines function\n\n    innerLevel() as pure\n      -> mainValue as Integer\n      <- rtn as Integer: 0\n      if mainValue > HIGH\n        rtn: 7\n      else if mainValue > LOW\n        rtn: 4\n\n    shallowNesting()\n      -> mainValue as Integer\n      <- result as Integer: 0\n      if mainValue > 0\n        result: innerLevel(mainValue)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11011"}
{"id":"errors/E11012/bad.ek9","url":"https://ek9.io/errors/E11012.html","title":"E11012: too many statements - extract functions","code":"#!ek9\ndefines module error.e11012.bad\n\n  defines class\n\n    TestClass\n      mainValue as Integer: 0\n\n      default operator ?\n\n      //This operator has 56 statements, exceeding the max of 50 for operators\n      //Note: Can't use 'pure' because we need to do mutation inside\n      operator :=:\n        -> other as TestClass\n        v1 <- 1\n        v2 <- v1 + 1\n        v3 <- v2 + 1\n        v4 <- v3 + 1\n        v5 <- v4 + 1\n        v6 <- v5 + 1\n        v7 <- v6 + 1\n        v8 <- v7 + 1\n        v9 <- v8 + 1\n        v10 <- v9 + 1\n        v11 <- v10 + 1\n        v12 <- v11 + 1\n        v13 <- v12 + 1\n        v14 <- v13 + 1\n        v15 <- v14 + 1\n        v16 <- v15 + 1\n        v17 <- v16 + 1\n        v18 <- v17 + 1\n        v19 <- v18 + 1\n        v20 <- v19 + 1\n        v21 <- v20 + 1\n        v22 <- v21 + 1\n        v23 <- v22 + 1\n        v24 <- v23 + 1\n        v25 <- v24 + 1\n        v26 <- v25 + 1\n        v27 <- v26 + 1\n        v28 <- v27 + 1\n        v29 <- v28 + 1\n        v30 <- v29 + 1\n        v31 <- v30 + 1\n        v32 <- v31 + 1\n        v33 <- v32 + 1\n        v34 <- v33 + 1\n        v35 <- v34 + 1\n        v36 <- v35 + 1\n        v37 <- v36 + 1\n        v38 <- v37 + 1\n        v39 <- v38 + 1\n        v40 <- v39 + 1\n        v41 <- v40 + 1\n        v42 <- v41 + 1\n        v43 <- v42 + 1\n        v44 <- v43 + 1\n        v45 <- v44 + 1\n        v46 <- v45 + 1\n        v47 <- v46 + 1\n        v48 <- v47 + 1\n        v49 <- v48 + 1\n        v50 <- v49 + 1\n        v51 <- v50 + 1\n        v52 <- v51 + 1\n        v53 <- v52 + 1\n        v54 <- v53 + 1\n        //Sum and store to ensure referenced\n        this.mainValue := v54","expectedOutput":null,"kind":"bad","errors":["E11012"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11012/good.ek9","url":"https://ek9.io/errors/E11012.html","title":"Keep an operator short - extract the work into a function","code":"#!ek9\ndefines module error.e11012.good\n\n  defines function\n\n    chained()\n      -> start as Integer\n      <- rtn as Integer: start + 53\n\n  defines class\n\n    TestClass\n      mainValue as Integer: 0\n\n      operator :=:\n        -> other as TestClass\n        this.mainValue := chained(other.mainValue)\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11012"}
{"id":"errors/E11013/bad.ek9","url":"https://ek9.io/errors/E11013.html","title":"E11013: excessive expression complexity - extract intermediate variables","code":"#!ek9\ndefines module error.e11013.bad\n\n  defines function\n\n    chosen()\n      ->\n        first as Integer\n        second as Integer\n        third as Integer\n        fourth as Integer\n      <- rtn as Integer: ((first ?: second) <? third) >? fourth","expectedOutput":null,"kind":"bad","errors":["E11013"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11013/good.ek9","url":"https://ek9.io/errors/E11013.html","title":"Name the intermediate values","code":"#!ek9\ndefines module error.e11013.good\n\n  defines function\n\n    chosen()\n      ->\n        first as Integer\n        second as Integer\n        third as Integer\n        fourth as Integer\n      <- rtn as Integer?\n      available <- first ?: second\n      lower <- available <? third\n      rtn: lower >? fourth","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11013"}
{"id":"errors/E11014/bad.ek9","url":"https://ek9.io/errors/E11014.html","title":"E11014: low cohesion - class has disconnected method groups, consider splitting","code":"#!ek9\ndefines module error.e11014.bad\n\n  defines class\n\n    LowCohesionClass\n      //9 separate fields - each used by only one method\n      field1 as Integer: 1\n      field2 as Integer: 2\n      field3 as Integer: 3\n      field4 as Integer: 4\n      field5 as Integer: 5\n      field6 as Integer: 6\n      field7 as Integer: 7\n      field8 as Integer: 8\n      field9 as Integer: 9\n\n      //9 methods - each uses only one field, creating 9 disconnected components\n      //LCOM4 = 9 > 8 (class threshold)\n\n      method1()\n        <- rtn as Integer: field1\n\n      method2()\n        <- rtn as Integer: field2\n\n      method3()\n        <- rtn as Integer: field3\n\n      method4()\n        <- rtn as Integer: field4\n\n      method5()\n        <- rtn as Integer: field5\n\n      method6()\n        <- rtn as Integer: field6\n\n      method7()\n        <- rtn as Integer: field7\n\n      method8()\n        <- rtn as Integer: field8\n\n      method9()\n        <- rtn as Integer: field9\n\n      //Custom isSet that only accesses field1 - doesn't connect other methods\n      override operator ? as pure\n        <- rtn as Boolean: field1?","expectedOutput":null,"kind":"bad","errors":["E11014"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11014/good.ek9","url":"https://ek9.io/errors/E11014.html","title":"Split the class so each one keeps the data its methods use together","code":"#!ek9\ndefines module error.e11014.good\n\n  defines class\n\n    Counter\n      count as Integer: 0\n      step as Integer: 1\n\n      increment()\n        count += step\n\n      current()\n        <- rtn as Integer: count\n\n      reset()\n        count: 0\n        step: 1\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11014"}
{"id":"errors/E11015/bad.ek9","url":"https://ek9.io/errors/E11015.html","title":"E11015: excessive efferent coupling - depends on too many types","code":"#!ek9\ndefines module error.e11015.bad\n\n  //Define 9 helper types to create coupling\n  defines record\n    TypeA\n      mainValue as Integer: 0\n      default operator ?\n    TypeB\n      mainValue as Integer: 0\n      default operator ?\n    TypeC\n      mainValue as Integer: 0\n      default operator ?\n    TypeD\n      mainValue as Integer: 0\n      default operator ?\n    TypeE\n      mainValue as Integer: 0\n      default operator ?\n    TypeF\n      mainValue as Integer: 0\n      default operator ?\n    TypeG\n      mainValue as Integer: 0\n      default operator ?\n    TypeH\n      mainValue as Integer: 0\n      default operator ?\n    TypeI\n      mainValue as Integer: 0\n      default operator ?\n\n  defines function\n\n    TooManyDependencies()\n      ->\n        a as TypeA\n        b as TypeB\n        c as TypeC\n        d as TypeD\n        e as TypeE\n        f as TypeF\n        g as TypeG\n        h as TypeH\n      <-\n        result as TypeI?\n\n      //Use all parameters to avoid dead code warnings\n      require a? and b? and c? and d?\n      require e? and f? and g? and h?\n      result :=? TypeI()","expectedOutput":null,"kind":"bad","errors":["E11015"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11015/good.ek9","url":"https://ek9.io/errors/E11015.html","title":"Group the values that travel together into one record","code":"#!ek9\ndefines module error.e11015.good\n\n  defines record\n\n    Order\n      item as String: String()\n      quantity as Integer: 0\n\n      default operator ?\n\n    Shipping\n      address as String: String()\n      express as Boolean: false\n\n      default operator ?\n\n    Receipt\n      summary as String: String()\n\n      default operator ?\n\n  defines function\n\n    fewerDependencies()\n      ->\n        order as Order\n        shipping as Shipping\n      <- result as Receipt?\n      require order? and shipping?\n      result :=? Receipt()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11015"}
{"id":"errors/E11016/bad/excessiveModuleCoupling.ek9","url":"https://ek9.io/errors/E11016.html","title":"E11016: excessive module coupling - references too many external modules","code":"#!ek9\n//Module-level error: this module references 11 external modules (threshold is 10)\ndefines module error.e11016.bad\n\n  references\n    error.e11016.bad.eight::Type8\n    error.e11016.bad.eleven::Type11\n    error.e11016.bad.five::Type5\n    error.e11016.bad.four::Type4\n    error.e11016.bad.nine::Type9\n    error.e11016.bad.one::Type1\n    error.e11016.bad.seven::Type7\n    error.e11016.bad.six::Type6\n    error.e11016.bad.ten::Type10\n    error.e11016.bad.three::Type3\n    error.e11016.bad.two::Type2\n\n  defines class\n    HighModuleCouplingClass\n      dep1 as Type1: Type1()\n      dep2 as Type2: Type2()\n      dep3 as Type3: Type3()\n      dep4 as Type4: Type4()\n      dep5 as Type5: Type5()\n      dep6 as Type6: Type6()\n      dep7 as Type7: Type7()\n      dep8 as Type8: Type8()\n      dep9 as Type9: Type9()\n      dep10 as Type10: Type10()\n      dep11 as Type11: Type11()\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E11016"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11016/bad/externalone.ek9","url":"https://ek9.io/errors/E11016.html","title":"E11016: excessive module coupling - references too many external modules","code":"#!ek9\ndefines module error.e11016.bad.one\n  defines record\n    Type1\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E11016"],"validation":"a file of the error example E11016/bad/: compiled with the example's other files, it reports nothing itself, and the example fails with exactly the errors listed in errors (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11016/bad/externaltwo.ek9","url":"https://ek9.io/errors/E11016.html","title":"E11016: excessive module coupling - references too many external modules","code":"#!ek9\ndefines module error.e11016.bad.two\n  defines record\n    Type2\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E11016"],"validation":"a file of the error example E11016/bad/: compiled with the example's other files, it reports nothing itself, and the example fails with exactly the errors listed in errors (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11016/bad/externalthree.ek9","url":"https://ek9.io/errors/E11016.html","title":"E11016: excessive module coupling - references too many external modules","code":"#!ek9\ndefines module error.e11016.bad.three\n  defines record\n    Type3\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E11016"],"validation":"a file of the error example E11016/bad/: compiled with the example's other files, it reports nothing itself, and the example fails with exactly the errors listed in errors (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11016/bad/externalfour.ek9","url":"https://ek9.io/errors/E11016.html","title":"E11016: excessive module coupling - references too many external modules","code":"#!ek9\ndefines module error.e11016.bad.four\n  defines record\n    Type4\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E11016"],"validation":"a file of the error example E11016/bad/: compiled with the example's other files, it reports nothing itself, and the example fails with exactly the errors listed in errors (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11016/bad/externalfive.ek9","url":"https://ek9.io/errors/E11016.html","title":"E11016: excessive module coupling - references too many external modules","code":"#!ek9\ndefines module error.e11016.bad.five\n  defines record\n    Type5\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E11016"],"validation":"a file of the error example E11016/bad/: compiled with the example's other files, it reports nothing itself, and the example fails with exactly the errors listed in errors (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11016/bad/externalsix.ek9","url":"https://ek9.io/errors/E11016.html","title":"E11016: excessive module coupling - references too many external modules","code":"#!ek9\ndefines module error.e11016.bad.six\n  defines record\n    Type6\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E11016"],"validation":"a file of the error example E11016/bad/: compiled with the example's other files, it reports nothing itself, and the example fails with exactly the errors listed in errors (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11016/bad/externalseven.ek9","url":"https://ek9.io/errors/E11016.html","title":"E11016: excessive module coupling - references too many external modules","code":"#!ek9\ndefines module error.e11016.bad.seven\n  defines record\n    Type7\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E11016"],"validation":"a file of the error example E11016/bad/: compiled with the example's other files, it reports nothing itself, and the example fails with exactly the errors listed in errors (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11016/bad/externaleight.ek9","url":"https://ek9.io/errors/E11016.html","title":"E11016: excessive module coupling - references too many external modules","code":"#!ek9\ndefines module error.e11016.bad.eight\n  defines record\n    Type8\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E11016"],"validation":"a file of the error example E11016/bad/: compiled with the example's other files, it reports nothing itself, and the example fails with exactly the errors listed in errors (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11016/bad/externalnine.ek9","url":"https://ek9.io/errors/E11016.html","title":"E11016: excessive module coupling - references too many external modules","code":"#!ek9\ndefines module error.e11016.bad.nine\n  defines record\n    Type9\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E11016"],"validation":"a file of the error example E11016/bad/: compiled with the example's other files, it reports nothing itself, and the example fails with exactly the errors listed in errors (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11016/bad/externalten.ek9","url":"https://ek9.io/errors/E11016.html","title":"E11016: excessive module coupling - references too many external modules","code":"#!ek9\ndefines module error.e11016.bad.ten\n  defines record\n    Type10\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E11016"],"validation":"a file of the error example E11016/bad/: compiled with the example's other files, it reports nothing itself, and the example fails with exactly the errors listed in errors (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11016/bad/externaleleven.ek9","url":"https://ek9.io/errors/E11016.html","title":"E11016: excessive module coupling - references too many external modules","code":"#!ek9\ndefines module error.e11016.bad.eleven\n  defines record\n    Type11\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E11016"],"validation":"a file of the error example E11016/bad/: compiled with the example's other files, it reports nothing itself, and the example fails with exactly the errors listed in errors (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11016/good/core.ek9","url":"https://ek9.io/errors/E11016.html","title":"Split the module by responsibility: each part depends on ten or fewer modules","code":"#!ek9\ndefines module error.e11016.good\n\n  references\n    error.e11016.good.five::Type5\n    error.e11016.good.four::Type4\n    error.e11016.good.one::Type1\n    error.e11016.good.six::Type6\n    error.e11016.good.three::Type3\n    error.e11016.good.two::Type2\n\n  defines class\n    CoreServices\n      dep1 as Type1: Type1()\n      dep2 as Type2: Type2()\n      dep3 as Type3: Type3()\n      dep4 as Type4: Type4()\n      dep5 as Type5: Type5()\n      dep6 as Type6: Type6()\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11016"}
{"id":"errors/E11016/good/reporting.ek9","url":"https://ek9.io/errors/E11016.html","title":"Split the module by responsibility: each part depends on ten or fewer modules","code":"#!ek9\ndefines module error.e11016.good.reporting\n\n  references\n    error.e11016.good.eight::Type8\n    error.e11016.good.eleven::Type11\n    error.e11016.good.nine::Type9\n    error.e11016.good.seven::Type7\n    error.e11016.good.ten::Type10\n\n  defines class\n    ReportingServices\n      dep7 as Type7: Type7()\n      dep8 as Type8: Type8()\n      dep9 as Type9: Type9()\n      dep10 as Type10: Type10()\n      dep11 as Type11: Type11()\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11016"}
{"id":"errors/E11016/good/externalone.ek9","url":"https://ek9.io/errors/E11016.html","title":"Split the module by responsibility: each part depends on ten or fewer modules","code":"#!ek9\ndefines module error.e11016.good.one\n  defines record\n    Type1\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11016"}
{"id":"errors/E11016/good/externaltwo.ek9","url":"https://ek9.io/errors/E11016.html","title":"Split the module by responsibility: each part depends on ten or fewer modules","code":"#!ek9\ndefines module error.e11016.good.two\n  defines record\n    Type2\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11016"}
{"id":"errors/E11016/good/externalthree.ek9","url":"https://ek9.io/errors/E11016.html","title":"Split the module by responsibility: each part depends on ten or fewer modules","code":"#!ek9\ndefines module error.e11016.good.three\n  defines record\n    Type3\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11016"}
{"id":"errors/E11016/good/externalfour.ek9","url":"https://ek9.io/errors/E11016.html","title":"Split the module by responsibility: each part depends on ten or fewer modules","code":"#!ek9\ndefines module error.e11016.good.four\n  defines record\n    Type4\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11016"}
{"id":"errors/E11016/good/externalfive.ek9","url":"https://ek9.io/errors/E11016.html","title":"Split the module by responsibility: each part depends on ten or fewer modules","code":"#!ek9\ndefines module error.e11016.good.five\n  defines record\n    Type5\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11016"}
{"id":"errors/E11016/good/externalsix.ek9","url":"https://ek9.io/errors/E11016.html","title":"Split the module by responsibility: each part depends on ten or fewer modules","code":"#!ek9\ndefines module error.e11016.good.six\n  defines record\n    Type6\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11016"}
{"id":"errors/E11016/good/externalseven.ek9","url":"https://ek9.io/errors/E11016.html","title":"Split the module by responsibility: each part depends on ten or fewer modules","code":"#!ek9\ndefines module error.e11016.good.seven\n  defines record\n    Type7\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11016"}
{"id":"errors/E11016/good/externaleight.ek9","url":"https://ek9.io/errors/E11016.html","title":"Split the module by responsibility: each part depends on ten or fewer modules","code":"#!ek9\ndefines module error.e11016.good.eight\n  defines record\n    Type8\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11016"}
{"id":"errors/E11016/good/externalnine.ek9","url":"https://ek9.io/errors/E11016.html","title":"Split the module by responsibility: each part depends on ten or fewer modules","code":"#!ek9\ndefines module error.e11016.good.nine\n  defines record\n    Type9\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11016"}
{"id":"errors/E11016/good/externalten.ek9","url":"https://ek9.io/errors/E11016.html","title":"Split the module by responsibility: each part depends on ten or fewer modules","code":"#!ek9\ndefines module error.e11016.good.ten\n  defines record\n    Type10\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11016"}
{"id":"errors/E11016/good/externaleleven.ek9","url":"https://ek9.io/errors/E11016.html","title":"Split the module by responsibility: each part depends on ten or fewer modules","code":"#!ek9\ndefines module error.e11016.good.eleven\n  defines record\n    Type11\n      mainValue as Integer: 0\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11016"}
{"id":"errors/E11017/bad.ek9","url":"https://ek9.io/errors/E11017.html","title":"E11017: low module cohesion - constructs share little commonality","code":"#!ek9\n//Module-level error: 61 disconnected groups out of 61 constructs (100% > 88%)\ndefines module error.e11017.bad\n\n  //61 independent records - none reference each other's types\n  //Each forms its own disconnected group\n\n  defines record\n    Record01\n      mainValue as Integer: 1\n      default operator ?\n\n    Record02\n      mainValue as Integer: 2\n      default operator ?\n\n    Record03\n      mainValue as Integer: 3\n      default operator ?\n\n    Record04\n      mainValue as Integer: 4\n      default operator ?\n\n    Record05\n      mainValue as Integer: 5\n      default operator ?\n\n    Record06\n      mainValue as Integer: 6\n      default operator ?\n\n    Record07\n      mainValue as Integer: 7\n      default operator ?\n\n    Record08\n      mainValue as Integer: 8\n      default operator ?\n\n    Record09\n      mainValue as Integer: 9\n      default operator ?\n\n    Record10\n      mainValue as Integer: 10\n      default operator ?\n\n    Record11\n      mainValue as Integer: 11\n      default operator ?\n\n    Record12\n      mainValue as Integer: 12\n      default operator ?\n\n    Record13\n      mainValue as Integer: 13\n      default operator ?\n\n    Record14\n      mainValue as Integer: 14\n      default operator ?\n\n    Record15\n      mainValue as Integer: 15\n      default operator ?\n\n    Record16\n      mainValue as Integer: 16\n      default operator ?\n\n    Record17\n      mainValue as Integer: 17\n      default operator ?\n\n    Record18\n      mainValue as Integer: 18\n      default operator ?\n\n    Record19\n      mainValue as Integer: 19\n      default operator ?\n\n    Record20\n      mainValue as Integer: 20\n      default operator ?\n\n    Record21\n      mainValue as Integer: 21\n      default operator ?\n\n    Record22\n      mainValue as Integer: 22\n      default operator ?\n\n    Record23\n      mainValue as Integer: 23\n      default operator ?\n\n    Record24\n      mainValue as Integer: 24\n      default operator ?\n\n    Record25\n      mainValue as Integer: 25\n      default operator ?\n\n    Record26\n      mainValue as Integer: 26\n      default operator ?\n\n    Record27\n      mainValue as Integer: 27\n      default operator ?\n\n    Record28\n      mainValue as Integer: 28\n      default operator ?\n\n    Record29\n      mainValue as Integer: 29\n      default operator ?\n\n    Record30\n      mainValue as Integer: 30\n      default operator ?\n\n    Record31\n      mainValue as Integer: 31\n      default operator ?\n\n    Record32\n      mainValue as Integer: 32\n      default operator ?\n\n    Record33\n      mainValue as Integer: 33\n      default operator ?\n\n    Record34\n      mainValue as Integer: 34\n      default operator ?\n\n    Record35\n      mainValue as Integer: 35\n      default operator ?\n\n    Record36\n      mainValue as Integer: 36\n      default operator ?\n\n    Record37\n      mainValue as Integer: 37\n      default operator ?\n\n    Record38\n      mainValue as Integer: 38\n      default operator ?\n\n    Record39\n      mainValue as Integer: 39\n      default operator ?\n\n    Record40\n      mainValue as Integer: 40\n      default operator ?\n\n    Record41\n      mainValue as Integer: 41\n      default operator ?\n\n    Record42\n      mainValue as Integer: 42\n      default operator ?\n\n    Record43\n      mainValue as Integer: 43\n      default operator ?\n\n    Record44\n      mainValue as Integer: 44\n      default operator ?\n\n    Record45\n      mainValue as Integer: 45\n      default operator ?\n\n    Record46\n      mainValue as Integer: 46\n      default operator ?\n\n    Record47\n      mainValue as Integer: 47\n      default operator ?\n\n    Record48\n      mainValue as Integer: 48\n      default operator ?\n\n    Record49\n      mainValue as Integer: 49\n      default operator ?\n\n    Record50\n      mainValue as Integer: 50\n      default operator ?\n\n    Record51\n      mainValue as Integer: 51\n      default operator ?\n\n    Record52\n      mainValue as Integer: 52\n      default operator ?\n\n    Record53\n      mainValue as Integer: 53\n      default operator ?\n\n    Record54\n      mainValue as Integer: 54\n      default operator ?\n\n    Record55\n      mainValue as Integer: 55\n      default operator ?\n\n    Record56\n      mainValue as Integer: 56\n      default operator ?\n\n    Record57\n      mainValue as Integer: 57\n      default operator ?\n\n    Record58\n      mainValue as Integer: 58\n      default operator ?\n\n    Record59\n      mainValue as Integer: 59\n      default operator ?\n\n    Record60\n      mainValue as Integer: 60\n      default operator ?\n\n    Record61\n      mainValue as Integer: 61\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E11017"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11017/good.ek9","url":"https://ek9.io/errors/E11017.html","title":"Keep a module to constructs that work together; move unrelated ones to their own modules","code":"#!ek9\ndefines module error.e11017.good\n\n  defines record\n\n    Address\n      street as String: String()\n      city as String: String()\n\n      default operator ?\n\n    Customer\n      name as String: String()\n      address as Address: Address()\n\n      default operator ?\n\n  defines function\n\n    label()\n      -> customer as Customer\n      <- rtn as String: `${customer.name}, ${customer.address.city}`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11017"}
{"id":"errors/E11018/bad.ek9","url":"https://ek9.io/errors/E11018.html","title":"E11018: unused captured variable in dynamic function or class","code":"#!ek9\ndefines module error.e11018.bad\n\n  defines program\n    ShowUnusedCapture()\n\n      stdout <- Stdout()\n\n      //'second' is captured but the hand-written 'operator ?' only checks 'first'.\n      pair <- Pair(first: \"hello\", second: \"world\") as class\n        override operator ? as pure\n          <- rtn as Boolean: first?\n\n      stdout.println(`${pair?}`)","expectedOutput":null,"kind":"bad","errors":["E11018"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11018/good.ek9","url":"https://ek9.io/errors/E11018.html","title":"Use every captured value - here the generated operator ? checks them all","code":"#!ek9\ndefines module error.e11018.good\n\n  defines program\n    ShowPositive()\n\n      stdout <- Stdout()\n\n      //Both captures are read implicitly by the synthesised 'default operator ?'.\n      pair <- Pair(first: \"hello\", second: \"world\") as class\n        default operator ?\n\n      stdout.println(`${pair?}`)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11018"}
{"id":"errors/E11019/bad.ek9","url":"https://ek9.io/errors/E11019.html","title":"E11019: excessive inheritance depth - consider delegation with 'by'","code":"#!ek9\ndefines module error.e11019.bad\n\n  defines class\n\n    Level1 as open\n      value1 as Integer: 1\n\n      default operator ?\n\n    Level2 extends Level1 as open\n      value2 as Integer: 2\n\n      default operator ?\n\n    Level3 extends Level2 as open\n      value3 as Integer: 3\n\n      default operator ?\n\n    Level4 extends Level3 as open\n      value4 as Integer: 4\n\n      default operator ?\n\n    Level5 extends Level4 as open\n      value5 as Integer: 5\n\n      default operator ?\n\n    //This class has depth 5 which exceeds maximum of 4\n    Level6 extends Level5\n      value6 as Integer: 6\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E11019"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11019/good.ek9","url":"https://ek9.io/errors/E11019.html","title":"Keep the hierarchy shallow - delegate with by instead of extending again","code":"#!ek9\ndefines module error.e11019.good\n\n  defines trait\n\n    Describes\n      describe() as abstract\n        <- rtn as String?\n\n  defines class\n\n    Level1 as open\n      value1 as Integer: 1\n      default operator ?\n\n    Level2 extends Level1 as open\n      value2 as Integer: 2\n      default operator ?\n\n    Level3 extends Level2\n      value3 as Integer: 3\n      default operator ?\n\n    Description with trait of Describes\n      override describe()\n        <- rtn as String: \"a level\"\n\n    Composed with trait of Describes by description\n      description as Describes: Description()\n      level as Level3: Level3()\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11019"}
{"id":"errors/E11020/bad.ek9","url":"https://ek9.io/errors/E11020.html","title":"E11020: combined complexity and size exceeds maintainability threshold","code":"#!ek9\ndefines module error.e11020.bad\n\n  defines function\n\n    combinedTooHigh()\n      ->\n        counter1 as Integer\n        counter2 as Integer\n        counter3 as Integer\n        counter4 as Integer\n        counter5 as Integer\n      <-\n        rtn as Integer: 0\n\n      //90 variable declarations (each counts as 1 statement)\n      v1 <- 1\n      v2 <- v1 + 1\n      v3 <- v2 + 1\n      v4 <- v3 + 1\n      v5 <- v4 + 1\n      v6 <- v5 + 1\n      v7 <- v6 + 1\n      v8 <- v7 + 1\n      v9 <- v8 + 1\n      v10 <- v9 + 1\n      v11 <- v10 + 1\n      v12 <- v11 + 1\n      v13 <- v12 + 1\n      v14 <- v13 + 1\n      v15 <- v14 + 1\n      v16 <- v15 + 1\n      v17 <- v16 + 1\n      v18 <- v17 + 1\n      v19 <- v18 + 1\n      v20 <- v19 + 1\n      v21 <- v20 + 1\n      v22 <- v21 + 1\n      v23 <- v22 + 1\n      v24 <- v23 + 1\n      v25 <- v24 + 1\n      v26 <- v25 + 1\n      v27 <- v26 + 1\n      v28 <- v27 + 1\n      v29 <- v28 + 1\n      v30 <- v29 + 1\n      v31 <- v30 + 1\n      v32 <- v31 + 1\n      v33 <- v32 + 1\n      v34 <- v33 + 1\n      v35 <- v34 + 1\n      v36 <- v35 + 1\n      v37 <- v36 + 1\n      v38 <- v37 + 1\n      v39 <- v38 + 1\n      v40 <- v39 + 1\n      v41 <- v40 + 1\n      v42 <- v41 + 1\n      v43 <- v42 + 1\n      v44 <- v43 + 1\n      v45 <- v44 + 1\n      v46 <- v45 + 1\n      v47 <- v46 + 1\n      v48 <- v47 + 1\n      v49 <- v48 + 1\n      v50 <- v49 + 1\n      v51 <- v50 + 1\n      v52 <- v51 + 1\n      v53 <- v52 + 1\n      v54 <- v53 + 1\n      v55 <- v54 + 1\n      v56 <- v55 + 1\n      v57 <- v56 + 1\n      v58 <- v57 + 1\n      v59 <- v58 + 1\n      v60 <- v59 + 1\n      v61 <- v60 + 1\n      v62 <- v61 + 1\n      v63 <- v62 + 1\n      v64 <- v63 + 1\n      v65 <- v64 + 1\n      v66 <- v65 + 1\n      v67 <- v66 + 1\n      v68 <- v67 + 1\n      v69 <- v68 + 1\n      v70 <- v69 + 1\n      v71 <- v70 + 1\n      v72 <- v71 + 1\n      v73 <- v72 + 1\n      v74 <- v73 + 1\n      v75 <- v74 + 1\n      v76 <- v75 + 1\n      v77 <- v76 + 1\n      v78 <- v77 + 1\n      v79 <- v78 + 1\n      v80 <- v79 + 1\n      v81 <- v80 + 1\n      v82 <- v81 + 1\n      v83 <- v82 + 1\n      v84 <- v83 + 1\n      v85 <- v84 + 1\n      v86 <- v85 + 1\n      v87 <- v86 + 1\n      v88 <- v87 + 1\n      v89 <- v88 + 1\n      v90 <- v89 + 1\n\n      //18 if statements with comparisons (each if adds +1 complexity, each > adds +1 complexity)\n      //Each if is also a statement\n      if counter1 > 0\n        v1 := v1 + 1\n\n      if counter2 > 0\n        v2 := v2 + 1\n\n      if counter3 > 0\n        v3 := v3 + 1\n\n      if counter4 > 0\n        v4 := v4 + 1\n\n      if counter5 > 0\n        v5 := v5 + 1\n\n      if v1 > v2\n        v6 := v6 + 1\n\n      if v2 > v3\n        v7 := v7 + 1\n\n      if v3 > v4\n        v8 := v8 + 1\n\n      if v4 > v5\n        v9 := v9 + 1\n\n      if v5 > v6\n        v10 := v10 + 1\n\n      if v6 > v7\n        v11 := v11 + 1\n\n      if v7 > v8\n        v12 := v12 + 1\n\n      if v8 > v9\n        v13 := v13 + 1\n\n      if v9 > v10\n        v14 := v14 + 1\n\n      if v10 > v11\n        v15 := v15 + 1\n\n      if v11 > v12\n        v16 := v16 + 1\n\n      if v12 > v13\n        v17 := v17 + 1\n\n      if v13 > v14\n        v18 := v18 + 1\n\n      //Final assignment reads the eighteen updated above; the rest feed one another up to v90\n      rtn := v1+v2+v3+v4+v5+v6+v7+v8+v9+v10+v11+v12+v13+v14+v15+v16+v17+v18+v90","expectedOutput":null,"kind":"bad","errors":["E11020"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11020/good.ek9","url":"https://ek9.io/errors/E11020.html","title":"Split a long, branching function into focused steps","code":"#!ek9\ndefines module error.e11020.good\n\n  defines function\n\n    validated()\n      ->\n        first as Integer\n        second as Integer\n      <- rtn as Boolean: first > 0 and second > 0\n\n    combined()\n      ->\n        first as Integer\n        second as Integer\n      <- rtn as Integer: first + second\n\n    combinedWithinLimits()\n      ->\n        first as Integer\n        second as Integer\n      <- rtn as Integer: 0\n      if validated(first, second)\n        rtn: combined(first, second)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11020"}
{"id":"errors/E11021/bad.ek9","url":"https://ek9.io/errors/E11021.html","title":"E11021: cognitive complexity exceeds limit - extract functions","code":"#!ek9\ndefines module error.e11021.bad\n\n  defines function\n\n    getA()\n      <- rtn as String: \"a\"\n\n    getB()\n      <- rtn as String: \"b\"\n\n    getC()\n      <- rtn as String: \"c\"\n\n    getD()\n      <- rtn as String: \"d\"\n\n    getE()\n      <- rtn as String: \"e\"\n\n    getF()\n      <- rtn as String: \"f\"\n\n    deepGuardChain()\n      <- result as String: \"\"\n\n      if a <- getA()\n        if b <- getB()\n          if c <- getC()\n            if d <- getD()\n              if e <- getE()\n                if f <- getF()\n                  result: `${a}${b}${c}${d}${e}${f}`","expectedOutput":null,"kind":"bad","errors":["E11021"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11021/good.ek9","url":"https://ek9.io/errors/E11021.html","title":"Gather the values first, then make one decision","code":"#!ek9\ndefines module error.e11021.good\n\n  defines function\n\n    getA()\n      <- rtn as String: \"a\"\n\n    getB()\n      <- rtn as String: \"b\"\n\n    getC()\n      <- rtn as String: \"c\"\n\n    combined()\n      <- result as String: \"\"\n      a <- getA()\n      b <- getB()\n      c <- getC()\n      if a? and b? and c?\n        result: `${a}${b}${c}`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11021"}
{"id":"errors/E11022/bad.ek9","url":"https://ek9.io/errors/E11022.html","title":"E11022: class has component characteristics - use 'defines component'","code":"#!ek9\ndefines module error.e11022.bad\n\n  defines trait\n    ServiceA\n      doA() as abstract\n    ServiceB\n      doB() as abstract\n    ServiceC\n      doC() as abstract\n    ServiceD\n      doD() as abstract\n\n  defines class\n    //Concrete implementations of the traits\n    ServiceAImpl with trait of ServiceA\n      override doA()\n        require true\n    ServiceBImpl with trait of ServiceB\n      override doB()\n        require true\n    ServiceCImpl with trait of ServiceC\n      override doC()\n        require true\n    ServiceDImpl with trait of ServiceD\n      override doD()\n        require true\n\n  defines class\n\n    PureCoordinator\n      //4 service (trait) fields initialized to implementations\n      //0 data fields = should be component\n      serviceA as ServiceA: ServiceAImpl()\n      serviceB as ServiceB: ServiceBImpl()\n      serviceC as ServiceC: ServiceCImpl()\n      serviceD as ServiceD: ServiceDImpl()\n\n      orchestrate()\n        serviceA.doA()\n        serviceB.doB()\n        serviceC.doC()\n        serviceD.doD()\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E11022"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11022/good.ek9","url":"https://ek9.io/errors/E11022.html","title":"A type that only coordinates services is a component","code":"#!ek9\ndefines module error.e11022.good\n\n  defines trait\n\n    ServiceA\n      doA() as abstract\n\n    ServiceB\n      doB() as abstract\n\n  defines class\n\n    ServiceAImpl with trait of ServiceA\n      override doA()\n        stdout <- Stdout()\n        stdout.println(\"A\")\n\n    ServiceBImpl with trait of ServiceB\n      override doB()\n        stdout <- Stdout()\n        stdout.println(\"B\")\n\n  defines component\n\n    Coordinator\n      serviceA as ServiceA: ServiceAImpl()\n      serviceB as ServiceB: ServiceBImpl()\n\n      orchestrate()\n        serviceA.doA()\n        serviceB.doB()\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11022"}
{"id":"errors/E11023/bad.ek9","url":"https://ek9.io/errors/E11023.html","title":"E11023: manual delegation detected - use 'by' keyword","code":"#!ek9\ndefines module error.e11023.bad\n\n  defines trait\n    Processor\n      process() as abstract\n      validate() as abstract\n      transform() as abstract\n      finalize() as abstract\n      cleanup() as abstract\n      prepare() as abstract\n      execute() as abstract\n\n  defines class\n    ProcessorImpl with trait of Processor\n      override process()\n        require true\n      override validate()\n        require true\n      override transform()\n        require true\n      override finalize()\n        require true\n      override cleanup()\n        require true\n      override prepare()\n        require true\n      override execute()\n        require true\n\n  defines class\n\n    ManualDelegator with trait of Processor\n      //Has a field compatible with the trait\n      delegate as Processor: ProcessorImpl()\n\n      //Manually overrides all 7 methods (100% > 70% threshold)\n      //This is boilerplate - should use 'by delegate'\n      override process()\n        delegate.process()\n      override validate()\n        delegate.validate()\n      override transform()\n        delegate.transform()\n      override finalize()\n        delegate.finalize()\n      override cleanup()\n        delegate.cleanup()\n      override prepare()\n        delegate.prepare()\n      override execute()\n        delegate.execute()\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E11023"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11023/good.ek9","url":"https://ek9.io/errors/E11023.html","title":"Delegate the trait with by","code":"#!ek9\ndefines module error.e11023.good\n\n  defines trait\n\n    Processor\n      process() as abstract\n      validate() as abstract\n\n  defines class\n\n    ProcessorImpl with trait of Processor\n      override process()\n        stdout <- Stdout()\n        stdout.println(\"process\")\n\n      override validate()\n        stdout <- Stdout()\n        stdout.println(\"validate\")\n\n    Delegator with trait of Processor by delegate\n      delegate as Processor: ProcessorImpl()\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11023"}
{"id":"errors/E11023/good_selective.ek9","url":"https://ek9.io/errors/E11023.html","title":"Delegate with 'by' and override only the methods that need custom logic","code":"#!ek9\ndefines module error.e11023.good.selective\n\n  defines trait\n    Processor\n      process() as abstract\n      validate() as abstract\n        -> request as String\n        <- rtn as Boolean?\n\n  defines class\n    ProcessorImpl with trait of Processor\n      override process()\n        stdout <- Stdout()\n        stdout.println(\"process\")\n      override validate()\n        -> request as String\n        <- rtn as Boolean: not request.empty()\n\n    //'process()' still delegates; only 'validate()' adds logging\n    Delegator with trait of Processor by delegate\n      delegate as Processor: ProcessorImpl()\n\n      override validate()\n        -> request as String\n        <- rtn as Boolean: delegate.validate(request)\n        stdout <- Stdout()\n        stdout.println(`Validating: ${request}`)\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11023"}
{"id":"errors/E11024/bad.ek9","url":"https://ek9.io/errors/E11024.html","title":"E11024: class mixes data and service coordination - split into class + component","code":"#!ek9\ndefines module error.e11024.bad\n\n  defines trait\n    Persistable\n      save() as abstract\n      load() as abstract\n\n  defines class\n    Repository with trait of Persistable\n      override save()\n        require true\n      override load()\n        require true\n\n  defines trait\n    NotificationService\n      notify() as abstract\n    AuditService\n      audit() as abstract\n    ValidationService\n      validate() as abstract\n\n  defines class\n    NotifierImpl with trait of NotificationService\n      override notify()\n        require true\n    AuditorImpl with trait of AuditService\n      override audit()\n        require true\n    ValidatorImpl with trait of ValidationService\n      override validate()\n        require true\n\n  defines class\n\n    MixedResponsibilities with trait of Persistable by repo\n      //Uses 'by' delegation - good so far\n      repo as Persistable: Repository()\n\n      //But also has 3+ additional service fields - wants to be a component!\n      notifier as NotificationService: NotifierImpl()\n      auditor as AuditService: AuditorImpl()\n      validator as ValidationService: ValidatorImpl()\n\n      //Has data fields too - so it's NOT pure component (doesn't trigger E11022)\n      //But the mix of 'by' + 3 services + data = hybrid (triggers E11024)\n      currentData as String: \"initial\"\n      counter as Integer: 0\n\n      //This class is trying to do too much:\n      //- It delegates persistence (class pattern with 'by')\n      //- It coordinates multiple services (component pattern)\n      //- It holds data (class pattern)\n      doWork()\n        validator.validate()\n        repo.save()\n        notifier.notify()\n        auditor.audit()\n        counter: counter + 1\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E11024"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11024/good.ek9","url":"https://ek9.io/errors/E11024.html","title":"Split it: a class for the data, a component for the coordination","code":"#!ek9\ndefines module error.e11024.good\n\n  defines trait\n\n    Persistable\n      save() as abstract\n\n    NotificationService\n      notify() as abstract\n\n  defines class\n\n    Repository with trait of Persistable\n      override save()\n        stdout <- Stdout()\n        stdout.println(\"saved\")\n\n    NotifierImpl with trait of NotificationService\n      override notify()\n        stdout <- Stdout()\n        stdout.println(\"notified\")\n\n    Record with trait of Persistable by repo\n      repo as Persistable: Repository()\n      currentData as String: \"initial\"\n      counter as Integer: 0\n\n      touch()\n        counter: counter + 1\n\n      default operator ?\n\n  defines component\n\n    Workflow\n      notifier as NotificationService: NotifierImpl()\n\n      run()\n        -> item as Record\n        item.save()\n        item.touch()\n        notifier.notify()\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11024"}
{"id":"errors/E11025/bad.ek9","url":"https://ek9.io/errors/E11025.html","title":"E11025: class has too many service and data fields - split into component + data class","code":"#!ek9\ndefines module error.e11025.bad\n\n  defines trait\n    ValidatorService\n      validate() as abstract\n    PricingService\n      calculatePrice() as abstract\n    ShippingService\n      ship() as abstract\n    NotificationService\n      notify() as abstract\n\n  defines class\n    ValidatorImpl with trait of ValidatorService\n      override validate()\n        require true\n    PricerImpl with trait of PricingService\n      override calculatePrice()\n        require true\n    ShipperImpl with trait of ShippingService\n      override ship()\n        require true\n    NotifierImpl with trait of NotificationService\n      override notify()\n        require true\n\n  defines record\n    Order\n      id as String: String()\n      item as String: String()\n\n      default operator ?\n\n    Amount\n      amount as Float: 0.0\n      currency as String: \"USD\"\n\n      default operator ?\n\n    Address\n      street as String: String()\n      city as String: String()\n\n      default operator ?\n\n  defines class\n\n    OrderProcessor\n      //3 service fields\n      validator as ValidatorService: ValidatorImpl()\n      pricer as PricingService: PricerImpl()\n      shipper as ShippingService: ShipperImpl()\n      //3 data fields\n      currentOrder as Order: Order()\n      totalAmount as Amount: Amount()\n      shippingAddress as Address: Address()\n\n      process()\n        validator.validate()\n\n      default operator ?\n\n  defines class\n\n    MassiveBlob\n      //4 service fields\n      validator as ValidatorService: ValidatorImpl()\n      pricer as PricingService: PricerImpl()\n      shipper as ShippingService: ShipperImpl()\n      notifier as NotificationService: NotifierImpl()\n      //4 data fields\n      order1 as Order: Order()\n      order2 as Order: Order()\n      amount as Amount: Amount()\n      destination as Address: Address()\n\n      doWork()\n        validator.validate()\n\n      default operator ?\n\n  defines class\n    //OK: 2 services + 4 data = under threshold\n    DataClassWithHelpers\n      validator as ValidatorService: ValidatorImpl()\n      pricer as PricingService: PricerImpl()\n\n      order1 as Order: Order()\n      order2 as Order: Order()\n      amount as Amount: Amount()\n      destination as Address: Address()\n\n      doWork()\n        validator.validate()\n\n      default operator ?\n\n  defines class\n    //OK: 4 services + 2 data = under threshold\n    StatefulCoordinator\n      validator as ValidatorService: ValidatorImpl()\n      pricer as PricingService: PricerImpl()\n      shipper as ShippingService: ShipperImpl()\n      notifier as NotificationService: NotifierImpl()\n\n      currentOrder as Order: Order()\n      amount as Amount: Amount()\n\n      doWork()\n        validator.validate()\n\n      default operator ?\n\n  defines class\n    //OK: 3 services + 2 data = under threshold\n    JustUnderThreshold\n      validator as ValidatorService: ValidatorImpl()\n      pricer as PricingService: PricerImpl()\n      shipper as ShippingService: ShipperImpl()\n\n      order as Order: Order()\n      amount as Amount: Amount()\n\n      doWork()\n        validator.validate()\n\n      default operator ?\n\n  defines class\n    //OK: 2 services + 3 data = under threshold\n    OtherBoundary\n      validator as ValidatorService: ValidatorImpl()\n      pricer as PricingService: PricerImpl()\n\n      order as Order: Order()\n      amount as Amount: Amount()\n      destination as Address: Address()\n\n      doWork()\n        validator.validate()\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E11025"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11025/good.ek9","url":"https://ek9.io/errors/E11025.html","title":"Keep the services in a component and the data in a record","code":"#!ek9\ndefines module error.e11025.good\n\n  defines trait\n\n    ValidatorService\n      validate() as abstract\n\n    PricingService\n      calculatePrice() as abstract\n\n  defines class\n\n    ValidatorImpl with trait of ValidatorService\n      override validate()\n        stdout <- Stdout()\n        stdout.println(\"valid\")\n\n    PricerImpl with trait of PricingService\n      override calculatePrice()\n        stdout <- Stdout()\n        stdout.println(\"priced\")\n\n  defines record\n\n    Order\n      id as String: String()\n      item as String: String()\n\n      default operator ?\n\n  defines component\n\n    OrderProcessor\n      validator as ValidatorService: ValidatorImpl()\n      pricer as PricingService: PricerImpl()\n\n      process()\n        -> order as Order\n        require order?\n        validator.validate()\n        pricer.calculatePrice()\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11025"}
{"id":"errors/E11026/bad.ek9","url":"https://ek9.io/errors/E11026.html","title":"E11026: references not in alphabetical order - reorder for consistency","code":"#!ek9\ndefines module error.e11026.bad\n\n  references\n    org.ek9.lang::String\n    org.ek9.lang::Integer\n\n  defines function\n\n    describe()\n      -> count as Integer\n      <- rtn as String: $count","expectedOutput":null,"kind":"bad","errors":["E11026"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11026/good.ek9","url":"https://ek9.io/errors/E11026.html","title":"List the references in alphabetical order","code":"#!ek9\ndefines module error.e11026.good\n\n  references\n    org.ek9.lang::Integer\n    org.ek9.lang::String\n\n  defines function\n\n    describe()\n      -> count as Integer\n      <- rtn as String: $count","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11026"}
{"id":"errors/E11027/bad.ek9","url":"https://ek9.io/errors/E11027.html","title":"E11027: too many constructs in module - split into focused modules","code":"#!ek9\ndefines module error.e11027.bad\n\n  // 260 classes in one module: over the 250-construct cap, so E11027 is reported at the module.\n  // Every class extends BaseType, so the module is perfectly cohesive - E11017 stays silent. A module can be\n  // cohesive and still be too big: the size cap catches that on its own merit.\n  defines class\n\n    BaseType as open\n      identify()\n        <- rtn as Boolean: true\n\n    DerivedNumber0000 extends BaseType\n      describeNumber0000()\n        <- rtn as Boolean: true\n\n    DerivedNumber0001 extends BaseType\n      describeNumber0001()\n        <- rtn as Boolean: true\n\n    DerivedNumber0002 extends BaseType\n      describeNumber0002()\n        <- rtn as Boolean: true\n\n    DerivedNumber0003 extends BaseType\n      describeNumber0003()\n        <- rtn as Boolean: true\n\n    DerivedNumber0004 extends BaseType\n      describeNumber0004()\n        <- rtn as Boolean: true\n\n    DerivedNumber0005 extends BaseType\n      describeNumber0005()\n        <- rtn as Boolean: true\n\n    DerivedNumber0006 extends BaseType\n      describeNumber0006()\n        <- rtn as Boolean: true\n\n    DerivedNumber0007 extends BaseType\n      describeNumber0007()\n        <- rtn as Boolean: true\n\n    DerivedNumber0008 extends BaseType\n      describeNumber0008()\n        <- rtn as Boolean: true\n\n    DerivedNumber0009 extends BaseType\n      describeNumber0009()\n        <- rtn as Boolean: true\n\n    DerivedNumber0010 extends BaseType\n      describeNumber0010()\n        <- rtn as Boolean: true\n\n    DerivedNumber0011 extends BaseType\n      describeNumber0011()\n        <- rtn as Boolean: true\n\n    DerivedNumber0012 extends BaseType\n      describeNumber0012()\n        <- rtn as Boolean: true\n\n    DerivedNumber0013 extends BaseType\n      describeNumber0013()\n        <- rtn as Boolean: true\n\n    DerivedNumber0014 extends BaseType\n      describeNumber0014()\n        <- rtn as Boolean: true\n\n    DerivedNumber0015 extends BaseType\n      describeNumber0015()\n        <- rtn as Boolean: true\n\n    DerivedNumber0016 extends BaseType\n      describeNumber0016()\n        <- rtn as Boolean: true\n\n    DerivedNumber0017 extends BaseType\n      describeNumber0017()\n        <- rtn as Boolean: true\n\n    DerivedNumber0018 extends BaseType\n      describeNumber0018()\n        <- rtn as Boolean: true\n\n    DerivedNumber0019 extends BaseType\n      describeNumber0019()\n        <- rtn as Boolean: true\n\n    DerivedNumber0020 extends BaseType\n      describeNumber0020()\n        <- rtn as Boolean: true\n\n    DerivedNumber0021 extends BaseType\n      describeNumber0021()\n        <- rtn as Boolean: true\n\n    DerivedNumber0022 extends BaseType\n      describeNumber0022()\n        <- rtn as Boolean: true\n\n    DerivedNumber0023 extends BaseType\n      describeNumber0023()\n        <- rtn as Boolean: true\n\n    DerivedNumber0024 extends BaseType\n      describeNumber0024()\n        <- rtn as Boolean: true\n\n    DerivedNumber0025 extends BaseType\n      describeNumber0025()\n        <- rtn as Boolean: true\n\n    DerivedNumber0026 extends BaseType\n      describeNumber0026()\n        <- rtn as Boolean: true\n\n    DerivedNumber0027 extends BaseType\n      describeNumber0027()\n        <- rtn as Boolean: true\n\n    DerivedNumber0028 extends BaseType\n      describeNumber0028()\n        <- rtn as Boolean: true\n\n    DerivedNumber0029 extends BaseType\n      describeNumber0029()\n        <- rtn as Boolean: true\n\n    DerivedNumber0030 extends BaseType\n      describeNumber0030()\n        <- rtn as Boolean: true\n\n    DerivedNumber0031 extends BaseType\n      describeNumber0031()\n        <- rtn as Boolean: true\n\n    DerivedNumber0032 extends BaseType\n      describeNumber0032()\n        <- rtn as Boolean: true\n\n    DerivedNumber0033 extends BaseType\n      describeNumber0033()\n        <- rtn as Boolean: true\n\n    DerivedNumber0034 extends BaseType\n      describeNumber0034()\n        <- rtn as Boolean: true\n\n    DerivedNumber0035 extends BaseType\n      describeNumber0035()\n        <- rtn as Boolean: true\n\n    DerivedNumber0036 extends BaseType\n      describeNumber0036()\n        <- rtn as Boolean: true\n\n    DerivedNumber0037 extends BaseType\n      describeNumber0037()\n        <- rtn as Boolean: true\n\n    DerivedNumber0038 extends BaseType\n      describeNumber0038()\n        <- rtn as Boolean: true\n\n    DerivedNumber0039 extends BaseType\n      describeNumber0039()\n        <- rtn as Boolean: true\n\n    DerivedNumber0040 extends BaseType\n      describeNumber0040()\n        <- rtn as Boolean: true\n\n    DerivedNumber0041 extends BaseType\n      describeNumber0041()\n        <- rtn as Boolean: true\n\n    DerivedNumber0042 extends BaseType\n      describeNumber0042()\n        <- rtn as Boolean: true\n\n    DerivedNumber0043 extends BaseType\n      describeNumber0043()\n        <- rtn as Boolean: true\n\n    DerivedNumber0044 extends BaseType\n      describeNumber0044()\n        <- rtn as Boolean: true\n\n    DerivedNumber0045 extends BaseType\n      describeNumber0045()\n        <- rtn as Boolean: true\n\n    DerivedNumber0046 extends BaseType\n      describeNumber0046()\n        <- rtn as Boolean: true\n\n    DerivedNumber0047 extends BaseType\n      describeNumber0047()\n        <- rtn as Boolean: true\n\n    DerivedNumber0048 extends BaseType\n      describeNumber0048()\n        <- rtn as Boolean: true\n\n    DerivedNumber0049 extends BaseType\n      describeNumber0049()\n        <- rtn as Boolean: true\n\n    DerivedNumber0050 extends BaseType\n      describeNumber0050()\n        <- rtn as Boolean: true\n\n    DerivedNumber0051 extends BaseType\n      describeNumber0051()\n        <- rtn as Boolean: true\n\n    DerivedNumber0052 extends BaseType\n      describeNumber0052()\n        <- rtn as Boolean: true\n\n    DerivedNumber0053 extends BaseType\n      describeNumber0053()\n        <- rtn as Boolean: true\n\n    DerivedNumber0054 extends BaseType\n      describeNumber0054()\n        <- rtn as Boolean: true\n\n    DerivedNumber0055 extends BaseType\n      describeNumber0055()\n        <- rtn as Boolean: true\n\n    DerivedNumber0056 extends BaseType\n      describeNumber0056()\n        <- rtn as Boolean: true\n\n    DerivedNumber0057 extends BaseType\n      describeNumber0057()\n        <- rtn as Boolean: true\n\n    DerivedNumber0058 extends BaseType\n      describeNumber0058()\n        <- rtn as Boolean: true\n\n    DerivedNumber0059 extends BaseType\n      describeNumber0059()\n        <- rtn as Boolean: true\n\n    DerivedNumber0060 extends BaseType\n      describeNumber0060()\n        <- rtn as Boolean: true\n\n    DerivedNumber0061 extends BaseType\n      describeNumber0061()\n        <- rtn as Boolean: true\n\n    DerivedNumber0062 extends BaseType\n      describeNumber0062()\n        <- rtn as Boolean: true\n\n    DerivedNumber0063 extends BaseType\n      describeNumber0063()\n        <- rtn as Boolean: true\n\n    DerivedNumber0064 extends BaseType\n      describeNumber0064()\n        <- rtn as Boolean: true\n\n    DerivedNumber0065 extends BaseType\n      describeNumber0065()\n        <- rtn as Boolean: true\n\n    DerivedNumber0066 extends BaseType\n      describeNumber0066()\n        <- rtn as Boolean: true\n\n    DerivedNumber0067 extends BaseType\n      describeNumber0067()\n        <- rtn as Boolean: true\n\n    DerivedNumber0068 extends BaseType\n      describeNumber0068()\n        <- rtn as Boolean: true\n\n    DerivedNumber0069 extends BaseType\n      describeNumber0069()\n        <- rtn as Boolean: true\n\n    DerivedNumber0070 extends BaseType\n      describeNumber0070()\n        <- rtn as Boolean: true\n\n    DerivedNumber0071 extends BaseType\n      describeNumber0071()\n        <- rtn as Boolean: true\n\n    DerivedNumber0072 extends BaseType\n      describeNumber0072()\n        <- rtn as Boolean: true\n\n    DerivedNumber0073 extends BaseType\n      describeNumber0073()\n        <- rtn as Boolean: true\n\n    DerivedNumber0074 extends BaseType\n      describeNumber0074()\n        <- rtn as Boolean: true\n\n    DerivedNumber0075 extends BaseType\n      describeNumber0075()\n        <- rtn as Boolean: true\n\n    DerivedNumber0076 extends BaseType\n      describeNumber0076()\n        <- rtn as Boolean: true\n\n    DerivedNumber0077 extends BaseType\n      describeNumber0077()\n        <- rtn as Boolean: true\n\n    DerivedNumber0078 extends BaseType\n      describeNumber0078()\n        <- rtn as Boolean: true\n\n    DerivedNumber0079 extends BaseType\n      describeNumber0079()\n        <- rtn as Boolean: true\n\n    DerivedNumber0080 extends BaseType\n      describeNumber0080()\n        <- rtn as Boolean: true\n\n    DerivedNumber0081 extends BaseType\n      describeNumber0081()\n        <- rtn as Boolean: true\n\n    DerivedNumber0082 extends BaseType\n      describeNumber0082()\n        <- rtn as Boolean: true\n\n    DerivedNumber0083 extends BaseType\n      describeNumber0083()\n        <- rtn as Boolean: true\n\n    DerivedNumber0084 extends BaseType\n      describeNumber0084()\n        <- rtn as Boolean: true\n\n    DerivedNumber0085 extends BaseType\n      describeNumber0085()\n        <- rtn as Boolean: true\n\n    DerivedNumber0086 extends BaseType\n      describeNumber0086()\n        <- rtn as Boolean: true\n\n    DerivedNumber0087 extends BaseType\n      describeNumber0087()\n        <- rtn as Boolean: true\n\n    DerivedNumber0088 extends BaseType\n      describeNumber0088()\n        <- rtn as Boolean: true\n\n    DerivedNumber0089 extends BaseType\n      describeNumber0089()\n        <- rtn as Boolean: true\n\n    DerivedNumber0090 extends BaseType\n      describeNumber0090()\n        <- rtn as Boolean: true\n\n    DerivedNumber0091 extends BaseType\n      describeNumber0091()\n        <- rtn as Boolean: true\n\n    DerivedNumber0092 extends BaseType\n      describeNumber0092()\n        <- rtn as Boolean: true\n\n    DerivedNumber0093 extends BaseType\n      describeNumber0093()\n        <- rtn as Boolean: true\n\n    DerivedNumber0094 extends BaseType\n      describeNumber0094()\n        <- rtn as Boolean: true\n\n    DerivedNumber0095 extends BaseType\n      describeNumber0095()\n        <- rtn as Boolean: true\n\n    DerivedNumber0096 extends BaseType\n      describeNumber0096()\n        <- rtn as Boolean: true\n\n    DerivedNumber0097 extends BaseType\n      describeNumber0097()\n        <- rtn as Boolean: true\n\n    DerivedNumber0098 extends BaseType\n      describeNumber0098()\n        <- rtn as Boolean: true\n\n    DerivedNumber0099 extends BaseType\n      describeNumber0099()\n        <- rtn as Boolean: true\n\n    DerivedNumber0100 extends BaseType\n      describeNumber0100()\n        <- rtn as Boolean: true\n\n    DerivedNumber0101 extends BaseType\n      describeNumber0101()\n        <- rtn as Boolean: true\n\n    DerivedNumber0102 extends BaseType\n      describeNumber0102()\n        <- rtn as Boolean: true\n\n    DerivedNumber0103 extends BaseType\n      describeNumber0103()\n        <- rtn as Boolean: true\n\n    DerivedNumber0104 extends BaseType\n      describeNumber0104()\n        <- rtn as Boolean: true\n\n    DerivedNumber0105 extends BaseType\n      describeNumber0105()\n        <- rtn as Boolean: true\n\n    DerivedNumber0106 extends BaseType\n      describeNumber0106()\n        <- rtn as Boolean: true\n\n    DerivedNumber0107 extends BaseType\n      describeNumber0107()\n        <- rtn as Boolean: true\n\n    DerivedNumber0108 extends BaseType\n      describeNumber0108()\n        <- rtn as Boolean: true\n\n    DerivedNumber0109 extends BaseType\n      describeNumber0109()\n        <- rtn as Boolean: true\n\n    DerivedNumber0110 extends BaseType\n      describeNumber0110()\n        <- rtn as Boolean: true\n\n    DerivedNumber0111 extends BaseType\n      describeNumber0111()\n        <- rtn as Boolean: true\n\n    DerivedNumber0112 extends BaseType\n      describeNumber0112()\n        <- rtn as Boolean: true\n\n    DerivedNumber0113 extends BaseType\n      describeNumber0113()\n        <- rtn as Boolean: true\n\n    DerivedNumber0114 extends BaseType\n      describeNumber0114()\n        <- rtn as Boolean: true\n\n    DerivedNumber0115 extends BaseType\n      describeNumber0115()\n        <- rtn as Boolean: true\n\n    DerivedNumber0116 extends BaseType\n      describeNumber0116()\n        <- rtn as Boolean: true\n\n    DerivedNumber0117 extends BaseType\n      describeNumber0117()\n        <- rtn as Boolean: true\n\n    DerivedNumber0118 extends BaseType\n      describeNumber0118()\n        <- rtn as Boolean: true\n\n    DerivedNumber0119 extends BaseType\n      describeNumber0119()\n        <- rtn as Boolean: true\n\n    DerivedNumber0120 extends BaseType\n      describeNumber0120()\n        <- rtn as Boolean: true\n\n    DerivedNumber0121 extends BaseType\n      describeNumber0121()\n        <- rtn as Boolean: true\n\n    DerivedNumber0122 extends BaseType\n      describeNumber0122()\n        <- rtn as Boolean: true\n\n    DerivedNumber0123 extends BaseType\n      describeNumber0123()\n        <- rtn as Boolean: true\n\n    DerivedNumber0124 extends BaseType\n      describeNumber0124()\n        <- rtn as Boolean: true\n\n    DerivedNumber0125 extends BaseType\n      describeNumber0125()\n        <- rtn as Boolean: true\n\n    DerivedNumber0126 extends BaseType\n      describeNumber0126()\n        <- rtn as Boolean: true\n\n    DerivedNumber0127 extends BaseType\n      describeNumber0127()\n        <- rtn as Boolean: true\n\n    DerivedNumber0128 extends BaseType\n      describeNumber0128()\n        <- rtn as Boolean: true\n\n    DerivedNumber0129 extends BaseType\n      describeNumber0129()\n        <- rtn as Boolean: true\n\n    DerivedNumber0130 extends BaseType\n      describeNumber0130()\n        <- rtn as Boolean: true\n\n    DerivedNumber0131 extends BaseType\n      describeNumber0131()\n        <- rtn as Boolean: true\n\n    DerivedNumber0132 extends BaseType\n      describeNumber0132()\n        <- rtn as Boolean: true\n\n    DerivedNumber0133 extends BaseType\n      describeNumber0133()\n        <- rtn as Boolean: true\n\n    DerivedNumber0134 extends BaseType\n      describeNumber0134()\n        <- rtn as Boolean: true\n\n    DerivedNumber0135 extends BaseType\n      describeNumber0135()\n        <- rtn as Boolean: true\n\n    DerivedNumber0136 extends BaseType\n      describeNumber0136()\n        <- rtn as Boolean: true\n\n    DerivedNumber0137 extends BaseType\n      describeNumber0137()\n        <- rtn as Boolean: true\n\n    DerivedNumber0138 extends BaseType\n      describeNumber0138()\n        <- rtn as Boolean: true\n\n    DerivedNumber0139 extends BaseType\n      describeNumber0139()\n        <- rtn as Boolean: true\n\n    DerivedNumber0140 extends BaseType\n      describeNumber0140()\n        <- rtn as Boolean: true\n\n    DerivedNumber0141 extends BaseType\n      describeNumber0141()\n        <- rtn as Boolean: true\n\n    DerivedNumber0142 extends BaseType\n      describeNumber0142()\n        <- rtn as Boolean: true\n\n    DerivedNumber0143 extends BaseType\n      describeNumber0143()\n        <- rtn as Boolean: true\n\n    DerivedNumber0144 extends BaseType\n      describeNumber0144()\n        <- rtn as Boolean: true\n\n    DerivedNumber0145 extends BaseType\n      describeNumber0145()\n        <- rtn as Boolean: true\n\n    DerivedNumber0146 extends BaseType\n      describeNumber0146()\n        <- rtn as Boolean: true\n\n    DerivedNumber0147 extends BaseType\n      describeNumber0147()\n        <- rtn as Boolean: true\n\n    DerivedNumber0148 extends BaseType\n      describeNumber0148()\n        <- rtn as Boolean: true\n\n    DerivedNumber0149 extends BaseType\n      describeNumber0149()\n        <- rtn as Boolean: true\n\n    DerivedNumber0150 extends BaseType\n      describeNumber0150()\n        <- rtn as Boolean: true\n\n    DerivedNumber0151 extends BaseType\n      describeNumber0151()\n        <- rtn as Boolean: true\n\n    DerivedNumber0152 extends BaseType\n      describeNumber0152()\n        <- rtn as Boolean: true\n\n    DerivedNumber0153 extends BaseType\n      describeNumber0153()\n        <- rtn as Boolean: true\n\n    DerivedNumber0154 extends BaseType\n      describeNumber0154()\n        <- rtn as Boolean: true\n\n    DerivedNumber0155 extends BaseType\n      describeNumber0155()\n        <- rtn as Boolean: true\n\n    DerivedNumber0156 extends BaseType\n      describeNumber0156()\n        <- rtn as Boolean: true\n\n    DerivedNumber0157 extends BaseType\n      describeNumber0157()\n        <- rtn as Boolean: true\n\n    DerivedNumber0158 extends BaseType\n      describeNumber0158()\n        <- rtn as Boolean: true\n\n    DerivedNumber0159 extends BaseType\n      describeNumber0159()\n        <- rtn as Boolean: true\n\n    DerivedNumber0160 extends BaseType\n      describeNumber0160()\n        <- rtn as Boolean: true\n\n    DerivedNumber0161 extends BaseType\n      describeNumber0161()\n        <- rtn as Boolean: true\n\n    DerivedNumber0162 extends BaseType\n      describeNumber0162()\n        <- rtn as Boolean: true\n\n    DerivedNumber0163 extends BaseType\n      describeNumber0163()\n        <- rtn as Boolean: true\n\n    DerivedNumber0164 extends BaseType\n      describeNumber0164()\n        <- rtn as Boolean: true\n\n    DerivedNumber0165 extends BaseType\n      describeNumber0165()\n        <- rtn as Boolean: true\n\n    DerivedNumber0166 extends BaseType\n      describeNumber0166()\n        <- rtn as Boolean: true\n\n    DerivedNumber0167 extends BaseType\n      describeNumber0167()\n        <- rtn as Boolean: true\n\n    DerivedNumber0168 extends BaseType\n      describeNumber0168()\n        <- rtn as Boolean: true\n\n    DerivedNumber0169 extends BaseType\n      describeNumber0169()\n        <- rtn as Boolean: true\n\n    DerivedNumber0170 extends BaseType\n      describeNumber0170()\n        <- rtn as Boolean: true\n\n    DerivedNumber0171 extends BaseType\n      describeNumber0171()\n        <- rtn as Boolean: true\n\n    DerivedNumber0172 extends BaseType\n      describeNumber0172()\n        <- rtn as Boolean: true\n\n    DerivedNumber0173 extends BaseType\n      describeNumber0173()\n        <- rtn as Boolean: true\n\n    DerivedNumber0174 extends BaseType\n      describeNumber0174()\n        <- rtn as Boolean: true\n\n    DerivedNumber0175 extends BaseType\n      describeNumber0175()\n        <- rtn as Boolean: true\n\n    DerivedNumber0176 extends BaseType\n      describeNumber0176()\n        <- rtn as Boolean: true\n\n    DerivedNumber0177 extends BaseType\n      describeNumber0177()\n        <- rtn as Boolean: true\n\n    DerivedNumber0178 extends BaseType\n      describeNumber0178()\n        <- rtn as Boolean: true\n\n    DerivedNumber0179 extends BaseType\n      describeNumber0179()\n        <- rtn as Boolean: true\n\n    DerivedNumber0180 extends BaseType\n      describeNumber0180()\n        <- rtn as Boolean: true\n\n    DerivedNumber0181 extends BaseType\n      describeNumber0181()\n        <- rtn as Boolean: true\n\n    DerivedNumber0182 extends BaseType\n      describeNumber0182()\n        <- rtn as Boolean: true\n\n    DerivedNumber0183 extends BaseType\n      describeNumber0183()\n        <- rtn as Boolean: true\n\n    DerivedNumber0184 extends BaseType\n      describeNumber0184()\n        <- rtn as Boolean: true\n\n    DerivedNumber0185 extends BaseType\n      describeNumber0185()\n        <- rtn as Boolean: true\n\n    DerivedNumber0186 extends BaseType\n      describeNumber0186()\n        <- rtn as Boolean: true\n\n    DerivedNumber0187 extends BaseType\n      describeNumber0187()\n        <- rtn as Boolean: true\n\n    DerivedNumber0188 extends BaseType\n      describeNumber0188()\n        <- rtn as Boolean: true\n\n    DerivedNumber0189 extends BaseType\n      describeNumber0189()\n        <- rtn as Boolean: true\n\n    DerivedNumber0190 extends BaseType\n      describeNumber0190()\n        <- rtn as Boolean: true\n\n    DerivedNumber0191 extends BaseType\n      describeNumber0191()\n        <- rtn as Boolean: true\n\n    DerivedNumber0192 extends BaseType\n      describeNumber0192()\n        <- rtn as Boolean: true\n\n    DerivedNumber0193 extends BaseType\n      describeNumber0193()\n        <- rtn as Boolean: true\n\n    DerivedNumber0194 extends BaseType\n      describeNumber0194()\n        <- rtn as Boolean: true\n\n    DerivedNumber0195 extends BaseType\n      describeNumber0195()\n        <- rtn as Boolean: true\n\n    DerivedNumber0196 extends BaseType\n      describeNumber0196()\n        <- rtn as Boolean: true\n\n    DerivedNumber0197 extends BaseType\n      describeNumber0197()\n        <- rtn as Boolean: true\n\n    DerivedNumber0198 extends BaseType\n      describeNumber0198()\n        <- rtn as Boolean: true\n\n    DerivedNumber0199 extends BaseType\n      describeNumber0199()\n        <- rtn as Boolean: true\n\n    DerivedNumber0200 extends BaseType\n      describeNumber0200()\n        <- rtn as Boolean: true\n\n    DerivedNumber0201 extends BaseType\n      describeNumber0201()\n        <- rtn as Boolean: true\n\n    DerivedNumber0202 extends BaseType\n      describeNumber0202()\n        <- rtn as Boolean: true\n\n    DerivedNumber0203 extends BaseType\n      describeNumber0203()\n        <- rtn as Boolean: true\n\n    DerivedNumber0204 extends BaseType\n      describeNumber0204()\n        <- rtn as Boolean: true\n\n    DerivedNumber0205 extends BaseType\n      describeNumber0205()\n        <- rtn as Boolean: true\n\n    DerivedNumber0206 extends BaseType\n      describeNumber0206()\n        <- rtn as Boolean: true\n\n    DerivedNumber0207 extends BaseType\n      describeNumber0207()\n        <- rtn as Boolean: true\n\n    DerivedNumber0208 extends BaseType\n      describeNumber0208()\n        <- rtn as Boolean: true\n\n    DerivedNumber0209 extends BaseType\n      describeNumber0209()\n        <- rtn as Boolean: true\n\n    DerivedNumber0210 extends BaseType\n      describeNumber0210()\n        <- rtn as Boolean: true\n\n    DerivedNumber0211 extends BaseType\n      describeNumber0211()\n        <- rtn as Boolean: true\n\n    DerivedNumber0212 extends BaseType\n      describeNumber0212()\n        <- rtn as Boolean: true\n\n    DerivedNumber0213 extends BaseType\n      describeNumber0213()\n        <- rtn as Boolean: true\n\n    DerivedNumber0214 extends BaseType\n      describeNumber0214()\n        <- rtn as Boolean: true\n\n    DerivedNumber0215 extends BaseType\n      describeNumber0215()\n        <- rtn as Boolean: true\n\n    DerivedNumber0216 extends BaseType\n      describeNumber0216()\n        <- rtn as Boolean: true\n\n    DerivedNumber0217 extends BaseType\n      describeNumber0217()\n        <- rtn as Boolean: true\n\n    DerivedNumber0218 extends BaseType\n      describeNumber0218()\n        <- rtn as Boolean: true\n\n    DerivedNumber0219 extends BaseType\n      describeNumber0219()\n        <- rtn as Boolean: true\n\n    DerivedNumber0220 extends BaseType\n      describeNumber0220()\n        <- rtn as Boolean: true\n\n    DerivedNumber0221 extends BaseType\n      describeNumber0221()\n        <- rtn as Boolean: true\n\n    DerivedNumber0222 extends BaseType\n      describeNumber0222()\n        <- rtn as Boolean: true\n\n    DerivedNumber0223 extends BaseType\n      describeNumber0223()\n        <- rtn as Boolean: true\n\n    DerivedNumber0224 extends BaseType\n      describeNumber0224()\n        <- rtn as Boolean: true\n\n    DerivedNumber0225 extends BaseType\n      describeNumber0225()\n        <- rtn as Boolean: true\n\n    DerivedNumber0226 extends BaseType\n      describeNumber0226()\n        <- rtn as Boolean: true\n\n    DerivedNumber0227 extends BaseType\n      describeNumber0227()\n        <- rtn as Boolean: true\n\n    DerivedNumber0228 extends BaseType\n      describeNumber0228()\n        <- rtn as Boolean: true\n\n    DerivedNumber0229 extends BaseType\n      describeNumber0229()\n        <- rtn as Boolean: true\n\n    DerivedNumber0230 extends BaseType\n      describeNumber0230()\n        <- rtn as Boolean: true\n\n    DerivedNumber0231 extends BaseType\n      describeNumber0231()\n        <- rtn as Boolean: true\n\n    DerivedNumber0232 extends BaseType\n      describeNumber0232()\n        <- rtn as Boolean: true\n\n    DerivedNumber0233 extends BaseType\n      describeNumber0233()\n        <- rtn as Boolean: true\n\n    DerivedNumber0234 extends BaseType\n      describeNumber0234()\n        <- rtn as Boolean: true\n\n    DerivedNumber0235 extends BaseType\n      describeNumber0235()\n        <- rtn as Boolean: true\n\n    DerivedNumber0236 extends BaseType\n      describeNumber0236()\n        <- rtn as Boolean: true\n\n    DerivedNumber0237 extends BaseType\n      describeNumber0237()\n        <- rtn as Boolean: true\n\n    DerivedNumber0238 extends BaseType\n      describeNumber0238()\n        <- rtn as Boolean: true\n\n    DerivedNumber0239 extends BaseType\n      describeNumber0239()\n        <- rtn as Boolean: true\n\n    DerivedNumber0240 extends BaseType\n      describeNumber0240()\n        <- rtn as Boolean: true\n\n    DerivedNumber0241 extends BaseType\n      describeNumber0241()\n        <- rtn as Boolean: true\n\n    DerivedNumber0242 extends BaseType\n      describeNumber0242()\n        <- rtn as Boolean: true\n\n    DerivedNumber0243 extends BaseType\n      describeNumber0243()\n        <- rtn as Boolean: true\n\n    DerivedNumber0244 extends BaseType\n      describeNumber0244()\n        <- rtn as Boolean: true\n\n    DerivedNumber0245 extends BaseType\n      describeNumber0245()\n        <- rtn as Boolean: true\n\n    DerivedNumber0246 extends BaseType\n      describeNumber0246()\n        <- rtn as Boolean: true\n\n    DerivedNumber0247 extends BaseType\n      describeNumber0247()\n        <- rtn as Boolean: true\n\n    DerivedNumber0248 extends BaseType\n      describeNumber0248()\n        <- rtn as Boolean: true\n\n    DerivedNumber0249 extends BaseType\n      describeNumber0249()\n        <- rtn as Boolean: true\n\n    DerivedNumber0250 extends BaseType\n      describeNumber0250()\n        <- rtn as Boolean: true\n\n    DerivedNumber0251 extends BaseType\n      describeNumber0251()\n        <- rtn as Boolean: true\n\n    DerivedNumber0252 extends BaseType\n      describeNumber0252()\n        <- rtn as Boolean: true\n\n    DerivedNumber0253 extends BaseType\n      describeNumber0253()\n        <- rtn as Boolean: true\n\n    DerivedNumber0254 extends BaseType\n      describeNumber0254()\n        <- rtn as Boolean: true\n\n    DerivedNumber0255 extends BaseType\n      describeNumber0255()\n        <- rtn as Boolean: true\n\n    DerivedNumber0256 extends BaseType\n      describeNumber0256()\n        <- rtn as Boolean: true\n\n\n    DerivedNumber0257 extends BaseType\n      describeNumber0257()\n        <- rtn as Boolean: true\n\n    DerivedNumber0258 extends BaseType\n      describeNumber0258()\n        <- rtn as Boolean: true","expectedOutput":null,"kind":"bad","errors":["E11027"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11027/good.ek9","url":"https://ek9.io/errors/E11027.html","title":"Keep a module to the constructs that belong together","code":"#!ek9\ndefines module error.e11027.good\n\n  // A module of the constructs that genuinely belong together is far under the 250-construct cap.\n  // When a module grows past it, split along the seams of what its constructs reference.\n  defines class\n\n    BaseType as open\n      identify()\n        <- rtn as Boolean: true\n\n    DerivedNumber0000 extends BaseType\n      describeNumber0000()\n        <- rtn as Boolean: true\n\n    DerivedNumber0001 extends BaseType\n      describeNumber0001()\n        <- rtn as Boolean: true","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11027"}
{"id":"errors/E11030/bad.ek9","url":"https://ek9.io/errors/E11030.html","title":"E11030: confusingly similar variable names - rename for clarity","code":"#!ek9\ndefines module error.e11030.bad\n\n  defines function\n\n    similarLocalVariables()\n      <- result as String: \"\"\n\n      userName <- \"customer data\"\n      userNam <- \"other data\"\n      result: userName + userNam","expectedOutput":null,"kind":"bad","errors":["E11030"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11030/good.ek9","url":"https://ek9.io/errors/E11030.html","title":"Give the variables names that differ in meaning, not by a letter","code":"#!ek9\ndefines module error.e11030.good\n\n  defines function\n\n    distinctNames()\n      <- result as String: \"\"\n      customerName <- \"customer data\"\n      supplierName <- \"other data\"\n      result: customerName + supplierName","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11030"}
{"id":"errors/E11031/bad.ek9","url":"https://ek9.io/errors/E11031.html","title":"E11031: non-descriptive variable name - use meaningful identifier","code":"#!ek9\ndefines module error.e11031.bad\n\n  defines function\n\n    process1()\n      <- result as String: \"\"\n      temp <- \"mainValue\"  // Tier 1 banned\n      result: temp\n\n\n    process2()\n      <- result as Boolean: false\n      flag <- true  // Tier 1 banned\n      result: flag\n\n\n    process3()\n      <- result as String: \"\"\n      data <- \"info\"  // Tier 1 banned\n      result: data\n\n\n    process4()\n      <- result as Integer: 0\n      value <- 42  // Tier 1 banned\n      result: value\n\n\n    process5()\n      <- result as String: \"\"\n      obj <- \"something\"  // Tier 1 banned\n      result: obj\n\n    process6()\n      <- result as String: \"\"\n      buf <- \"\"  // Tier 1 banned\n      result: buf\n\n    process7()\n      ->\n        tmp as String  // Parameter with banned name\n      <-\n        result as String: \"\"\n      result: tmp\n\n\n    process8()\n      ->\n        val as Integer  // Parameter with banned name\n      <-\n        result as Integer: 0\n      result: val","expectedOutput":null,"kind":"bad","errors":["E11031"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11031/good.ek9","url":"https://ek9.io/errors/E11031.html","title":"Name what the value is for","code":"#!ek9\ndefines module error.e11031.good\n\n  defines function\n\n    greetingFor()\n      -> customerName as String\n      <- greeting as String: String()\n      salutation <- \"Hello, \"\n      greeting: salutation + customerName\n\n    isAdult()\n      -> ageInYears as Integer\n      <- adult as Boolean?\n      adultAge <- 18\n      adult: ageInYears >= adultAge","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11031"}
{"id":"errors/E11031/good_allowed.ek9","url":"https://ek9.io/errors/E11031.html","title":"Only the listed names are banned: short mathematical names, loop counters and compounds are fine","code":"#!ek9\ndefines module error.e11031.good.allowed\n\n  defines function\n\n    radius()\n      <- rtn as Float?\n      //Mathematical names\n      x <- 3.5\n      y <- 2.0\n      r <- sqrt (x * x + y * y)\n      //Loop counters\n      total <- 0\n      for i in 1 ... 3\n        for j in 1 ... 2\n          total += i * j\n      //A banned word inside a compound name\n      tempCelsius <- 21.5\n      customerData <- \"Steve\"\n      rtn: r + #^total + tempCelsius + #^length customerData","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11031"}
{"id":"errors/E11031/good_typed.ek9","url":"https://ek9.io/errors/E11031.html","title":"A specific type carries the meaning; a bare type needs a descriptive name","code":"#!ek9\ndefines module error.e11031.good.typed\n\n  defines function\n\n    //Money says what each value is, so a short name reads well\n    totalPaid()\n      ->\n        amount as Money\n        fee as Money\n      <- total as Money: amount + fee\n\n    //A bare Float says nothing about what it holds: the name has to\n    totalPaidInPounds()\n      ->\n        paymentAmount as Float\n        feeAmount as Float\n      <- total as Float: paymentAmount + feeAmount","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11031"}
{"id":"errors/E11032/bad.ek9","url":"https://ek9.io/errors/E11032.html","title":"E11032: variable name shadows operator keyword - use a more specific name","code":"#!ek9\ndefines module error.e11032.bad\n\n  defines function\n\n    demo()\n      <- rtn as String?\n      empty <- List() of String\n      length <- 42\n      contains <- true\n      rtn: `${empty} ${length} ${contains}`","expectedOutput":null,"kind":"bad","errors":["E11032"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11032/good.ek9","url":"https://ek9.io/errors/E11032.html","title":"Name what the value means, not the operator","code":"#!ek9\ndefines module error.e11032.good\n\n  defines function\n\n    demo()\n      <- rtn as String?\n      pendingItems <- List() of String\n      nameLength <- 42\n      hasItem <- true\n      rtn: `${length pendingItems} ${nameLength} ${hasItem}`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11032"}
{"id":"errors/E11040/bad.ek9","url":"https://ek9.io/errors/E11040.html","title":"E11040: too many injected fields - use a facade component to group dependencies","code":"#!ek9\ndefines module error.e11040.bad\n\n  defines component\n\n    ServiceA as abstract\n      doWorkA() as abstract\n        <- rtn as Boolean?\n\n      default operator ?\n\n    ServiceB as abstract\n      doWorkB() as abstract\n        <- rtn as Boolean?\n\n      default operator ?\n\n    ServiceC as abstract\n      doWorkC() as abstract\n        <- rtn as Boolean?\n\n      default operator ?\n\n    ServiceD as abstract\n      doWorkD() as abstract\n        <- rtn as Boolean?\n\n      default operator ?\n\n    ServiceE as abstract\n      doWorkE() as abstract\n        <- rtn as Boolean?\n\n      default operator ?\n\n    ExcessiveInjectionComponent\n      //5 injection fields exceeds limit of 4\n      svcA as ServiceA!\n      svcB as ServiceB!\n      svcC as ServiceC!\n      svcD as ServiceD!\n      svcE as ServiceE!\n\n      doAllWork()\n        <- rtn as Boolean: true\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E11040"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11040/good.ek9","url":"https://ek9.io/errors/E11040.html","title":"Group related dependencies behind a facade component","code":"#!ek9\ndefines module error.e11040.good\n\n  defines component\n\n    ServiceA as abstract\n      doWorkA() as abstract\n        <- rtn as Boolean?\n      default operator ?\n\n    ServiceB as abstract\n      doWorkB() as abstract\n        <- rtn as Boolean?\n      default operator ?\n\n    ServiceC as abstract\n      doWorkC() as abstract\n        <- rtn as Boolean?\n      default operator ?\n\n    ServiceD as abstract\n      doWorkD() as abstract\n        <- rtn as Boolean?\n      default operator ?\n\n    ServiceE as abstract\n      doWorkE() as abstract\n        <- rtn as Boolean?\n      default operator ?\n\n    Backend as abstract\n      doBackendWork() as abstract\n        <- rtn as Boolean?\n      default operator ?\n\n    FocusedComponent\n      svcA as ServiceA!\n      svcB as ServiceB!\n      backend as Backend!\n\n      doAllWork()\n        <- rtn as Boolean: svcA.doWorkA() and svcB.doWorkB() and backend.doBackendWork()\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11040"}
{"id":"errors/E11041/bad.ek9","url":"https://ek9.io/errors/E11041.html","title":"E11041: multiple methods use the same injected type - promote to a facade component","code":"#!ek9\ndefines module error.e11041.bad\n\n  defines component\n\n    AuditService as abstract\n      record() as abstract\n        -> msg as String\n      default operator ?\n\n    OrderProcessor\n\n      submit()\n        -> label as String\n        audit as AuditService!\n        audit.record(label)\n\n      cancel()\n        -> label as String\n        audit as AuditService!\n        audit.record(label)\n\n      refund()\n        -> label as String\n        audit as AuditService!\n        audit.record(label)\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E11041"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11041/good.ek9","url":"https://ek9.io/errors/E11041.html","title":"Inject it once, as a field the methods share","code":"#!ek9\ndefines module error.e11041.good\n\n  defines component\n\n    AuditService as abstract\n      record() as abstract\n        -> msg as String\n      default operator ?\n\n    OrderProcessor\n      audit as AuditService!\n\n      submit()\n        -> label as String\n        audit.record(label)\n\n      cancel()\n        -> label as String\n        audit.record(label)\n\n      refund()\n        -> label as String\n        audit.record(label)\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11041"}
{"id":"errors/E11042/bad.ek9","url":"https://ek9.io/errors/E11042.html","title":"E11042: application has too many registrations - split into focused applications","code":"#!ek9\ndefines module error.e11042.bad\n\n  defines component\n\n    Part1 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part1Impl is Part1\n      override id()\n        <- rtn as Integer: 1\n\n    Part2 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part2Impl is Part2\n      override id()\n        <- rtn as Integer: 2\n\n    Part3 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part3Impl is Part3\n      override id()\n        <- rtn as Integer: 3\n\n    Part4 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part4Impl is Part4\n      override id()\n        <- rtn as Integer: 4\n\n    Part5 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part5Impl is Part5\n      override id()\n        <- rtn as Integer: 5\n\n    Part6 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part6Impl is Part6\n      override id()\n        <- rtn as Integer: 6\n\n    Part7 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part7Impl is Part7\n      override id()\n        <- rtn as Integer: 7\n\n    Part8 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part8Impl is Part8\n      override id()\n        <- rtn as Integer: 8\n\n    Part9 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part9Impl is Part9\n      override id()\n        <- rtn as Integer: 9\n\n    Part10 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part10Impl is Part10\n      override id()\n        <- rtn as Integer: 10\n\n    Part11 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part11Impl is Part11\n      override id()\n        <- rtn as Integer: 11\n\n    Part12 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part12Impl is Part12\n      override id()\n        <- rtn as Integer: 12\n\n    Part13 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part13Impl is Part13\n      override id()\n        <- rtn as Integer: 13\n\n  defines application\n\n    everything\n      register Part1Impl() as Part1\n      register Part2Impl() as Part2\n      register Part3Impl() as Part3\n      register Part4Impl() as Part4\n      register Part5Impl() as Part5\n      register Part6Impl() as Part6\n      register Part7Impl() as Part7\n      register Part8Impl() as Part8\n      register Part9Impl() as Part9\n      register Part10Impl() as Part10\n      register Part11Impl() as Part11\n      register Part12Impl() as Part12\n      register Part13Impl() as Part13","expectedOutput":null,"kind":"bad","errors":["E11042"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11042/good.ek9","url":"https://ek9.io/errors/E11042.html","title":"Split it into focused applications","code":"#!ek9\ndefines module error.e11042.good\n\n  defines component\n\n    Part1 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part1Impl is Part1\n      override id()\n        <- rtn as Integer: 1\n\n    Part2 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part2Impl is Part2\n      override id()\n        <- rtn as Integer: 2\n\n    Part3 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part3Impl is Part3\n      override id()\n        <- rtn as Integer: 3\n\n    Part4 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part4Impl is Part4\n      override id()\n        <- rtn as Integer: 4\n\n    Part5 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part5Impl is Part5\n      override id()\n        <- rtn as Integer: 5\n\n    Part6 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part6Impl is Part6\n      override id()\n        <- rtn as Integer: 6\n\n    Part7 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part7Impl is Part7\n      override id()\n        <- rtn as Integer: 7\n\n    Part8 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part8Impl is Part8\n      override id()\n        <- rtn as Integer: 8\n\n    Part9 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part9Impl is Part9\n      override id()\n        <- rtn as Integer: 9\n\n    Part10 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part10Impl is Part10\n      override id()\n        <- rtn as Integer: 10\n\n    Part11 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part11Impl is Part11\n      override id()\n        <- rtn as Integer: 11\n\n    Part12 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part12Impl is Part12\n      override id()\n        <- rtn as Integer: 12\n\n    Part13 as abstract\n      id() as abstract\n        <- rtn as Integer?\n\n    Part13Impl is Part13\n      override id()\n        <- rtn as Integer: 13\n\n  defines application\n\n    partsOneToSeven\n      register Part1Impl() as Part1\n      register Part2Impl() as Part2\n      register Part3Impl() as Part3\n      register Part4Impl() as Part4\n      register Part5Impl() as Part5\n      register Part6Impl() as Part6\n      register Part7Impl() as Part7\n\n    partsEightToThirteen\n      register Part8Impl() as Part8\n      register Part9Impl() as Part9\n      register Part10Impl() as Part10\n      register Part11Impl() as Part11\n      register Part12Impl() as Part12\n      register Part13Impl() as Part13","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11042"}
{"id":"errors/E11043/bad.ek9","url":"https://ek9.io/errors/E11043.html","title":"E11043: method uses too many distinct injected types - extract to a dedicated component","code":"#!ek9\ndefines module error.e11043.bad\n\n  defines component\n\n    ServiceA as abstract\n      doA() as abstract\n        <- rtn as Boolean?\n      default operator ?\n\n    ServiceB as abstract\n      doB() as abstract\n        <- rtn as Boolean?\n      default operator ?\n\n    ServiceC as abstract\n      doC() as abstract\n        <- rtn as Boolean?\n      default operator ?\n\n    ServiceD as abstract\n      doD() as abstract\n        <- rtn as Boolean?\n      default operator ?\n\n    ServiceE as abstract\n      doE() as abstract\n        <- rtn as Boolean?\n      default operator ?\n\n  defines function\n\n    orchestrate()\n      <- rtn as Boolean?\n      a as ServiceA!\n      b as ServiceB!\n      c as ServiceC!\n      d as ServiceD!\n      e as ServiceE!\n      rtn: a.doA() and b.doB() and c.doC() and d.doD() and e.doE()","expectedOutput":null,"kind":"bad","errors":["E11043"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11043/good.ek9","url":"https://ek9.io/errors/E11043.html","title":"Let one injected facade coordinate the services","code":"#!ek9\ndefines module error.e11043.good\n\n  defines component\n\n    ServiceA as abstract\n      doA() as abstract\n        <- rtn as Boolean?\n      default operator ?\n\n    ServiceB as abstract\n      doB() as abstract\n        <- rtn as Boolean?\n      default operator ?\n\n    ServiceC as abstract\n      doC() as abstract\n        <- rtn as Boolean?\n      default operator ?\n\n    Coordinator as abstract\n      coordinate() as abstract\n        <- rtn as Boolean?\n      default operator ?\n\n  defines function\n\n    orchestrate()\n      <- rtn as Boolean?\n      a as ServiceA!\n      b as ServiceB!\n      c as ServiceC!\n      rest as Coordinator!\n      rtn: a.doA() and b.doB() and c.doC() and rest.coordinate()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11043"}
{"id":"errors/E11044/bad.ek9","url":"https://ek9.io/errors/E11044.html","title":"E11044: override method body is identical to super - remove the override","code":"#!ek9\ndefines module error.e11044.bad\n\n  defines class\n\n    Base as open\n      doWork()\n        <- rtn as String: \"working\"\n\n    Derived extends Base\n      override doWork()\n        <- rtn as String: \"working\"","expectedOutput":null,"kind":"bad","errors":["E11044"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11044/good.ek9","url":"https://ek9.io/errors/E11044.html","title":"Remove an override that repeats the super - or make it do something different","code":"#!ek9\ndefines module error.e11044.good\n\n  defines class\n\n    Base as open\n      doWork()\n        <- rtn as String: \"working\"\n\n    Derived extends Base\n\n    Shouty extends Base\n      override doWork()\n        <- rtn as String: \"WORKING\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11044"}
{"id":"errors/E11044/good_conflict.ek9","url":"https://ek9.io/errors/E11044.html","title":"An override two traits compel is never redundant","code":"#!ek9\ndefines module error.e11044.good.conflict\n\n  defines trait\n    Logger\n      log()\n        -> message as String\n        stdout <- Stdout()\n        stdout.println(message)\n\n    Auditor\n      log()\n        -> message as String\n        stdout <- Stdout()\n        stdout.println(message)\n\n  defines class\n    //Both traits supply log(): the override is REQUIRED (E06150), so it is not flagged\n    Service with trait of Logger, Auditor\n      override log()\n        -> message as String\n        stdout <- Stdout()\n        stdout.println(message)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11044"}
{"id":"errors/E11050/bad.ek9","url":"https://ek9.io/errors/E11050.html","title":"E11050: operator returns a value but result is discarded - assign to variable or use in expression","code":"#!ek9\ndefines module error.e11050.bad\n\n  defines function\n\n    testDiscardedComparisonOperator()\n      a <- \"hello\"\n      b <- \"world\"\n      a.==(b)\n\n    testDiscardedAddOperator()\n      a <- 10\n      b <- 20\n      a.+(b)\n\n    testDiscardedNotEqualOperator()\n      a <- \"hello\"\n      b <- \"world\"\n      a.<>(b)","expectedOutput":null,"kind":"bad","errors":["E11050"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11050/good.ek9","url":"https://ek9.io/errors/E11050.html","title":"Use the result of the operator","code":"#!ek9\ndefines module error.e11050.good\n\n  defines function\n\n    sameWord()\n      <- rtn as Boolean?\n      first <- \"hello\"\n      second <- \"world\"\n      rtn: first == second\n\n    total()\n      <- rtn as Integer?\n      first <- 10\n      second <- 20\n      rtn: first + second","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11050"}
{"id":"errors/E11051/bad.ek9","url":"https://ek9.io/errors/E11051.html","title":"E11051: pure method/function returns a value but result is discarded - a pure call with no side effects achieves nothing","code":"#!ek9\ndefines module error.e11051.bad\n\n  defines function\n\n    pureCompute() as pure\n      -> input as Integer\n      <- result as Integer: input * 2\n\n    testDiscardedPureFunctionCall()\n      pureCompute(42)\n\n  defines class\n\n    Calculator\n\n      add() as pure\n        -> operand as Integer\n        <- result as Integer: operand + 1\n\n    TestClass\n\n      testDiscardedPureMethodCall()\n        calc <- Calculator()\n        calc.add(10)","expectedOutput":null,"kind":"bad","errors":["E11051"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11051/good.ek9","url":"https://ek9.io/errors/E11051.html","title":"Use the result - discarding is only for a call made for its side effect","code":"#!ek9\ndefines module error.e11051.good\n\n  defines function\n\n    voidFunction()\n      Stdout().println(\"side effect\")\n\n    impureCompute()\n      <- result as Integer: 42\n\n    testVoidCallIsOk()\n      voidFunction()\n\n    testNonPureCallIsOk()\n      impureCompute()\n\n    testAssignedReturnIsOk()\n      result <- impureCompute()\n      Stdout().println($result)\n\n    testMutatingOperatorIsOk()\n      counter <- 0\n      counter++\n      counter += 5\n      Stdout().println($counter)\n\n    testStdoutIsOk()\n      Stdout().println(\"This is fine\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11051"}
{"id":"errors/E11052/bad.ek9","url":"https://ek9.io/errors/E11052.html","title":"E11052: method returns Result or Optional but result is discarded - must always be checked","code":"#!ek9\ndefines module error.e11052.bad\n\n  defines function\n\n    riskyOperation()\n      <- rtn <- Result(\"OK\", Integer())\n\n    findItem()\n      <- rtn <- Optional(\"Found\")\n\n    testDiscardedResult()\n      riskyOperation()\n\n    testDiscardedOptional()\n      findItem()","expectedOutput":null,"kind":"bad","errors":["E11052"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11052/good.ek9","url":"https://ek9.io/errors/E11052.html","title":"Check the Result or Optional you are given","code":"#!ek9\ndefines module error.e11052.good\n\n  defines function\n\n    riskyOperation()\n      <- rtn <- Result(\"OK\", Integer())\n\n    findItem()\n      <- rtn <- Optional(\"Found\")\n\n    useResult()\n      <- rtn as String: \"failed\"\n      outcome <- riskyOperation()\n      if outcome.isOk()\n        rtn: outcome.ok()\n\n    useOptional()\n      <- rtn as String: \"missing\"\n      found <- findItem()\n      if found?\n        rtn: found.get()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11052"}
{"id":"errors/E11053/bad.ek9","url":"https://ek9.io/errors/E11053.html","title":"E11053: data clump detected - extract a record to group repeated parameters","code":"#!ek9\n//Module-level error: 3 functions share 4 identical parameters (street, city, state, zipCode)\ndefines module error.e11053.bad\n\n  defines function\n\n    formatAddress()\n      ->\n        street as String\n        city as String\n        state as String\n        zipCode as String\n      <- result as String: `${street}, ${city}, ${state} ${zipCode}`\n\n    validateAddress()\n      ->\n        street as String\n        city as String\n        state as String\n        zipCode as String\n      <- valid as Boolean: street? and city? and state? and zipCode?\n\n    normalizeAddress()\n      ->\n        street as String\n        city as String\n        state as String\n        zipCode as String\n      <- result as String: `${street.upperCase()}, ${city.upperCase()}, ${state.upperCase()} ${zipCode}`","expectedOutput":null,"kind":"bad","errors":["E11053"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11053/good.ek9","url":"https://ek9.io/errors/E11053.html","title":"Group the parameters that always travel together into a record","code":"#!ek9\ndefines module error.e11053.good\n\n  defines record\n\n    Address\n      street as String: String()\n      city as String: String()\n      state as String: String()\n      zipCode as String: String()\n\n      default operator ?\n\n  defines function\n\n    formatAddress()\n      -> address as Address\n      <- result as String: `${address.street}, ${address.city}, ${address.state} ${address.zipCode}`\n\n    validateAddress()\n      -> address as Address\n      <- valid as Boolean: address?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11053"}
{"id":"errors/E11054/bad.ek9","url":"https://ek9.io/errors/E11054.html","title":"E11054: method chain traverses too many types - extract a function or use a pipeline","code":"#!ek9\ndefines module error.e11054.bad\n\n  defines class\n\n    Location\n      name as String: \"Leeds\"\n      getName()\n        <- rtn as String: name\n      default operator ?\n\n    Address\n      location as Location: Location()\n      getLocation()\n        <- rtn as Location: location\n      default operator ?\n\n    Customer\n      address as Address: Address()\n      getAddress()\n        <- rtn as Address: address\n      default operator ?\n\n    Order\n      customer as Customer: Customer()\n      getCustomer()\n        <- rtn as Customer: customer\n      default operator ?\n\n  defines function\n\n    getDeepValue()\n      -> order as Order\n      <- city as String: String()\n      city: order.getCustomer().getAddress().getLocation().getName()","expectedOutput":null,"kind":"bad","errors":["E11054"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11054/good.ek9","url":"https://ek9.io/errors/E11054.html","title":"Ask each type for what it knows - give Customer a method for the city","code":"#!ek9\ndefines module error.e11054.good\n\n  defines class\n\n    Location\n      name as String: \"Leeds\"\n      getName()\n        <- rtn as String: name\n      default operator ?\n\n    Address\n      location as Location: Location()\n      city()\n        <- rtn as String: location.getName()\n      default operator ?\n\n    Customer\n      address as Address: Address()\n      city()\n        <- rtn as String: address.city()\n      default operator ?\n\n    Order\n      customer as Customer: Customer()\n      getCustomer()\n        <- rtn as Customer: customer\n      default operator ?\n\n  defines function\n\n    getCustomerCity()\n      -> order as Order\n      <- city as String: order.getCustomer().city()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11054"}
{"id":"errors/E11055/bad.ek9","url":"https://ek9.io/errors/E11055.html","title":"E11055: constructor result is discarded - assign to a variable; if you need side effects, use a function","code":"#!ek9\ndefines module error.e11055.bad\n\n  defines class\n\n    Sensor\n      reading <- Float()\n\n      Sensor()\n        -> initialReading as Float\n        this.reading :=: initialReading\n\n      currentReading() as pure\n        <- rtn as Float: reading\n\n      default operator ?\n\n  defines function\n\n    testDiscardedBuiltInConstructor()\n      String(\"hello\")\n\n    testDiscardedBuiltInConstructorWithArg()\n      Integer(42)\n\n    testDiscardedUserClassConstructor()\n      Sensor(98.6)\n\n    testDiscardedExceptionConstructor()\n      Exception(\"something went wrong\")\n\n    testAssignedConstructorIsOk()\n      greeting <- String(\"hello\")\n      sensor <- Sensor(98.6)\n      Stdout().println(greeting)\n      Stdout().println($sensor.currentReading())\n\n    testConstructorInExpressionIsOk()\n      stdout <- Stdout()\n      stdout.println(String(\"used in expression\"))","expectedOutput":null,"kind":"bad","errors":["E11055"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11055/good.ek9","url":"https://ek9.io/errors/E11055.html","title":"Keep what you construct - or call a function if you only want its side effect","code":"#!ek9\ndefines module error.e11055.good\n\n  defines function\n\n    greeting()\n      <- rtn as String: String(\"hello\")\n\n    announce()\n      stdout <- Stdout()\n      stdout.println(greeting())","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11055"}
{"id":"errors/E11061/bad.ek9","url":"https://ek9.io/errors/E11061.html","title":"E11061: call passes 2+ Boolean literals positionally - use named arguments for clarity","code":"#!ek9\ndefines module error.e11061.bad\n\n  defines class\n\n    Connection\n      host as String: String()\n      port as Integer: 0\n      useSsl as Boolean: false\n      autoReconnect as Boolean: false\n\n      default private Connection()\n\n      Connection()\n        ->\n          host as String\n          port as Integer\n          useSsl as Boolean\n          autoReconnect as Boolean\n        this.host: host\n        this.port: port\n        this.useSsl: useSsl\n        this.autoReconnect: autoReconnect\n\n      default operator ?\n      default operator $\n\n  defines function\n\n    connect()\n      <- rtn as String?\n      connection <- Connection(\"db\", 5432, true, false)\n      rtn: $connection","expectedOutput":null,"kind":"bad","errors":["E11061"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11061/good.ek9","url":"https://ek9.io/errors/E11061.html","title":"Name the arguments","code":"#!ek9\ndefines module error.e11061.good\n\n  defines class\n\n    Connection\n      host as String: String()\n      port as Integer: 0\n      useSsl as Boolean: false\n      autoReconnect as Boolean: false\n\n      default private Connection()\n\n      Connection()\n        ->\n          host as String\n          port as Integer\n          useSsl as Boolean\n          autoReconnect as Boolean\n        this.host: host\n        this.port: port\n        this.useSsl: useSsl\n        this.autoReconnect: autoReconnect\n\n      default operator ?\n      default operator $\n\n  defines function\n\n    connect()\n      <- rtn as String?\n      connection <- Connection(host: \"db\", port: 5432, useSsl: true, autoReconnect: false)\n      rtn: $connection","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11061"}
{"id":"errors/E11062/bad.ek9","url":"https://ek9.io/errors/E11062.html","title":"E11062: call has 4+ positional arguments - use named arguments for clarity","code":"#!ek9\ndefines module error.e11062.bad\n\n  defines function\n\n    scheduleJob()\n      ->\n        jobName as String\n        targetPath as String\n        maxRetries as Integer\n        intervalMinutes as Integer\n      <- rtn as String: `${jobName} ${targetPath} ${maxRetries} ${intervalMinutes}`\n\n    backup()\n      <- rtn as String?\n      rtn: scheduleJob(\"backup\", \"/data\", 3, 60)","expectedOutput":null,"kind":"bad","errors":["E11062"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11062/good.ek9","url":"https://ek9.io/errors/E11062.html","title":"Name the arguments","code":"#!ek9\ndefines module error.e11062.good\n\n  defines function\n\n    scheduleJob()\n      ->\n        jobName as String\n        targetPath as String\n        maxRetries as Integer\n        intervalMinutes as Integer\n      <- rtn as String: `${jobName} ${targetPath} ${maxRetries} ${intervalMinutes}`\n\n    backup()\n      <- rtn as String?\n      rtn: scheduleJob(jobName: \"backup\", targetPath: \"/data\", maxRetries: 3, intervalMinutes: 60)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11062"}
{"id":"errors/E11064/bad.ek9","url":"https://ek9.io/errors/E11064.html","title":"E11064: literal in comparison/range - give it a meaningful name","code":"#!ek9\ndefines module error.e11064.bad\n\n  defines function\n\n    testIntegerInEquality()\n      -> count as Integer\n      <- result as Boolean: false\n      result: count == 42\n\n    testIntegerInNotEqual()\n      -> count as Integer\n      <- result as Boolean: false\n      result: count <> 42\n\n    testIntegerInGreaterThan()\n      -> attempts as Integer\n      <- result as Boolean: false\n      result: attempts > 3\n\n    testIntegerInLessThan()\n      -> score as Integer\n      <- result as Boolean: false\n      result: score < 50\n\n    testIntegerInGreaterEqual()\n      -> age as Integer\n      <- result as Boolean: false\n      result: age >= 18\n\n    testIntegerInLessEqual()\n      -> temperature as Integer\n      <- result as Boolean: false\n      result: temperature <= 100\n\n    testFloatInComparison()\n      -> ratio as Float\n      <- result as Boolean: false\n      result: ratio > 0.95\n\n    testComparisonOperator()\n      -> left as Integer\n      <- result as Integer: 0\n      result: left <=> 10","expectedOutput":null,"kind":"bad","errors":["E11064"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11064/good.ek9","url":"https://ek9.io/errors/E11064.html","title":"Give the literal a name","code":"#!ek9\ndefines module error.e11064.good\n\n  defines constant\n\n    ADULT_AGE <- 18\n\n  defines function\n\n    isAdult()\n      -> age as Integer\n      <- rtn as Boolean: age >= ADULT_AGE","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11064"}
{"id":"errors/E11064/good_local.ek9","url":"https://ek9.io/errors/E11064.html","title":"A local variable names a value specific to one function - declared after the returning variable","code":"#!ek9\ndefines module error.e11064.good.local\n\n  defines function\n\n    isExpensive() as pure\n      -> price as Float\n      <- rtn as Boolean?\n      //A local goes after the returning variable, never between '->' and '<-'\n      expensiveThreshold <- 50.0\n      rtn :=? price > expensiveThreshold","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11064"}
{"id":"errors/E11065/bad.ek9","url":"https://ek9.io/errors/E11065.html","title":"E11065: literal appears multiple times - extract to a named constant","code":"#!ek9\ndefines module error.e11065.bad\n\n  defines function\n\n    testRepeatedString()\n      stdout <- Stdout()\n      stdout.println(\"processing\")\n      stdout.println(\"processing\")\n      stdout.println(\"processing\")\n\n    //A constructor call is not exempt (D4): it was once, by the callee's name starting with an uppercase\n    //letter. Label the arguments - Cookie(name: \"session\", cookieValue: ...) - or name a shared value.\n    testRepeatedStringInConstructors()\n      c1 <- Cookie(\"session\", \"abc123\")\n      c2 <- Cookie(\"session\", \"def456\")\n      c3 <- Cookie(\"session\", \"ghi789\")\n      require c1? and c2? and c3?\n\n    //The same heuristic exempted any FUNCTION whose name starts with an uppercase letter.\n    testRepeatedStringToUppercaseFunction()\n      first <- Shout(\"hello\")\n      second <- Shout(\"hello\")\n      third <- Shout(\"hello\")\n      require first? and second? and third?\n\n    Shout()\n      -> text as String\n      <- rtn as String: text.upperCase()","expectedOutput":null,"kind":"bad","errors":["E11065"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11065/good.ek9","url":"https://ek9.io/errors/E11065.html","title":"Name the literal once, as a constant","code":"#!ek9\ndefines module error.e11065.good\n\n  defines constant\n\n    TAX_RATE <- 0.2\n\n  defines function\n\n    tax()\n      -> amount as Float\n      <- rtn as Float: amount * TAX_RATE\n\n    net()\n      -> amount as Float\n      <- rtn as Float: amount - amount * TAX_RATE\n\n    gross()\n      -> amount as Float\n      <- rtn as Float: amount + amount * TAX_RATE","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11065"}
{"id":"errors/E11066/bad/constants1.ek9","url":"https://ek9.io/errors/E11066.html","title":"E11066: constants should be consolidated into a single file","code":"#!ek9\ndefines module error.e11066.bad\n\n  defines constant\n    MAX_RETRIES <- 3\n    DEFAULT_TIMEOUT <- 30","expectedOutput":null,"kind":"bad","errors":["E11066"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11066/bad/constants2.ek9","url":"https://ek9.io/errors/E11066.html","title":"E11066: constants should be consolidated into a single file","code":"#!ek9\ndefines module error.e11066.bad\n\n  defines constant\n    BASE_URL <- \"https://example.com\"\n    API_VERSION <- 2","expectedOutput":null,"kind":"bad","errors":["E11066"],"validation":"a file of the error example E11066/bad/: compiled with the example's other files, it reports nothing itself, and the example fails with exactly the errors listed in errors (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11066/bad/constants3.ek9","url":"https://ek9.io/errors/E11066.html","title":"E11066: constants should be consolidated into a single file","code":"#!ek9\ndefines module error.e11066.bad\n\n  defines constant\n    LOG_LEVEL <- \"DEBUG\"\n    MAX_CONNECTIONS <- 100","expectedOutput":null,"kind":"bad","errors":["E11066"],"validation":"a file of the error example E11066/bad/: compiled with the example's other files, it reports nothing itself, and the example fails with exactly the errors listed in errors (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11066/good/constants.ek9","url":"https://ek9.io/errors/E11066.html","title":"One dedicated constants file; the other files of the module use them by name","code":"#!ek9\ndefines module error.e11066.good\n\n  defines constant\n    MAX_RETRIES <- 3\n    DEFAULT_TIMEOUT <- 30\n    BASE_URL <- \"https://example.com\"\n    API_VERSION <- 2\n    LOG_LEVEL <- \"DEBUG\"\n    MAX_CONNECTIONS <- 100","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11066"}
{"id":"errors/E11066/good/client.ek9","url":"https://ek9.io/errors/E11066.html","title":"One dedicated constants file; the other files of the module use them by name","code":"#!ek9\ndefines module error.e11066.good\n\n  defines function\n\n    endpoint() as pure\n      -> resource as String\n      <- url as String: `${BASE_URL}/v${API_VERSION}/${resource}`\n\n    connectionBudget() as pure\n      <- description as String: `${MAX_CONNECTIONS} connections, ${DEFAULT_TIMEOUT}s timeout, ${MAX_RETRIES} retries`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11066"}
{"id":"errors/E11066/good/logging.ek9","url":"https://ek9.io/errors/E11066.html","title":"One dedicated constants file; the other files of the module use them by name","code":"#!ek9\ndefines module error.e11066.good\n\n  defines function\n\n    logLine() as pure\n      -> message as String\n      <- line as String: `[${LOG_LEVEL}] ${message}`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11066"}
{"id":"errors/E11067/bad/processing.ek9","url":"https://ek9.io/errors/E11067.html","title":"E11067: module has many constants - consider a dedicated constants file","code":"#!ek9\ndefines module error.e11067.bad\n\n  defines constant\n    MAX_BATCH_SIZE <- 1000\n    MIN_BATCH_SIZE <- 10\n    DEFAULT_WORKERS <- 4\n    RETRY_DELAY <- 250ms\n    MAX_QUEUE_DEPTH <- 500","expectedOutput":null,"kind":"bad","errors":["E11067"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11067/bad/validation.ek9","url":"https://ek9.io/errors/E11067.html","title":"E11067: module has many constants - consider a dedicated constants file","code":"#!ek9\ndefines module error.e11067.bad\n\n  defines constant\n    MIN_NAME_LENGTH <- 2\n    MAX_NAME_LENGTH <- 100\n    DEFAULT_LOCALE <- \"en_GB\"\n    MAX_FIELD_COUNT <- 50\n    TRIM_WHITESPACE <- true","expectedOutput":null,"kind":"bad","errors":["E11067"],"validation":"a file of the error example E11067/bad/: compiled with the example's other files, it reports nothing itself, and the example fails with exactly the errors listed in errors (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11067/good/constants.ek9","url":"https://ek9.io/errors/E11067.html","title":"The ten constants in one dedicated file; the processing and validation files use them","code":"#!ek9\ndefines module error.e11067.good\n\n  defines constant\n    MAX_BATCH_SIZE <- 1000\n    MIN_BATCH_SIZE <- 10\n    DEFAULT_WORKERS <- 4\n    RETRY_DELAY <- 250ms\n    MAX_QUEUE_DEPTH <- 500\n    MIN_NAME_LENGTH <- 2\n    MAX_NAME_LENGTH <- 100\n    DEFAULT_LOCALE <- \"en_GB\"\n    MAX_FIELD_COUNT <- 50\n    TRIM_WHITESPACE <- true","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11067"}
{"id":"errors/E11067/good/processing.ek9","url":"https://ek9.io/errors/E11067.html","title":"The ten constants in one dedicated file; the processing and validation files use them","code":"#!ek9\ndefines module error.e11067.good\n\n  defines function\n\n    batchSizeFor() as pure\n      -> requested as Integer\n      <- size as Integer: MAX_BATCH_SIZE <? (MIN_BATCH_SIZE >? requested)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11067"}
{"id":"errors/E11067/good/validation.ek9","url":"https://ek9.io/errors/E11067.html","title":"The ten constants in one dedicated file; the processing and validation files use them","code":"#!ek9\ndefines module error.e11067.good\n\n  defines function\n\n    isValidName() as pure\n      -> name as String\n      <- valid as Boolean: length name >= MIN_NAME_LENGTH and length name <= MAX_NAME_LENGTH","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11067"}
{"id":"errors/E11068/bad.ek9","url":"https://ek9.io/errors/E11068.html","title":"E11068: string concatenation with 3+ parts - use string interpolation instead","code":"#!ek9\ndefines module error.e11068.bad\n\n  defines function\n\n    threePartChain()\n      -> name as String\n      <- result as String: String()\n      result: \"Hello \" + name + \"!\"\n\n    fourPartChain()\n      ->\n        first as String\n        last as String\n      <- result as String: String()\n      result: first + \" \" + last + \" here\"\n\n    fivePartChainWithDollar()\n      ->\n        x as Integer\n        y as Integer\n      <- result as String: String()\n      result: \"(\" + $x + \", \" + $y + \")\"","expectedOutput":null,"kind":"bad","errors":["E11068"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11068/good.ek9","url":"https://ek9.io/errors/E11068.html","title":"Use string interpolation","code":"#!ek9\ndefines module error.e11068.good\n\n  defines function\n\n    //Two-part concat is allowed (below threshold)\n    twoPartConcat()\n      -> name as String\n      <- result as String: String()\n      result: \"Hello \" + name\n\n    //Interpolation is fine (obviously)\n    interpolation()\n      -> name as String\n      <- result as String: `Hello ${name}!`\n\n    //Numeric addition is fine (not String type)\n    numericAddition()\n      ->\n        a as Integer\n        b as Integer\n        c as Integer\n      <- result as Integer: 0\n      result: a + b + c\n\n    //String concat as just two variables\n    twoVariables()\n      ->\n        first as String\n        last as String\n      <- result as String: String()\n      result: first + last","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11068"}
{"id":"errors/E11069/bad.ek9","url":"https://ek9.io/errors/E11069.html","title":"E11069: nested call chain exceeds one level - extract intermediate variable for readability","code":"#!ek9\ndefines module error.e11069.bad\n\n  defines function\n\n    Transformer() as pure abstract\n      -> input as String\n      <- output as String?\n\n    UpperTransformer() extends Transformer as pure\n      -> input as String\n      <- output as String: input.upperCase()\n\n    Maker() as abstract\n      -> seed as String\n      <- transformer as Transformer?\n\n    SimpleMaker() extends Maker\n      -> seed as String\n      <- transformer as Transformer: UpperTransformer\n\n    getMaker()\n      -> kind as String\n      <- maker as Maker: SimpleMaker\n\n      if kind == \"simple\"\n        maker: SimpleMaker\n\n    //Two levels deep: getMaker returns Maker, Maker returns Transformer, Transformer returns String\n    checkTwoLevelChain()\n      <- result as String?\n\n      result: getMaker(\"simple\")(\"seed\")(\"text\")","expectedOutput":null,"kind":"bad","errors":["E11069"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11069/good.ek9","url":"https://ek9.io/errors/E11069.html","title":"Name the intermediate result","code":"#!ek9\ndefines module error.e11069.good\n\n  defines constant\n\n    //'upper' appeared three times, which is E11065 (repeated magic literal). Naming it keeps this\n    //positive control clean - it exists to say nothing about call-chain depth, not to trip a\n    //different rule.\n    UPPER_TRANSFORM <- \"upper\"\n\n  defines function\n\n    Transformer() as pure abstract\n      -> input as String\n      <- output as String?\n\n    UpperTransformer() extends Transformer as pure\n      -> input as String\n      <- output as String: input.upperCase()\n\n    getTransformer()\n      -> mode as String\n      <- transformer as Transformer: UpperTransformer\n\n      if mode == \"lower\"\n        transformer: UpperTransformer\n\n    //Single-level chaining: valid functional pattern\n    checkSingleLevelChain()\n      <- result as String?\n      result: getTransformer(UPPER_TRANSFORM)(\"single level is fine\")\n\n    //Single-level chaining with objectAccess: also valid\n    checkSingleLevelWithChain()\n      <- result as String?\n      result: getTransformer(UPPER_TRANSFORM)(\"  chained  \").trim()\n\n    //Direct function call: not a chain at all\n    checkDirectCall()\n      <- result as String?\n      processor as Transformer: UpperTransformer\n      result: processor(\"direct delegate\")\n\n    //Decomposed two-level: the correct way to handle depth\n    checkDecomposedChain()\n      <- result as String?\n      transformer <- getTransformer(UPPER_TRANSFORM)\n      result: transformer(\"decomposed is clear\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11069"}
{"id":"errors/E11070/bad.ek9","url":"https://ek9.io/errors/E11070.html","title":"E11070: nested call in throw - extract intermediate variable for the exception","code":"#!ek9\ndefines module error.e11070.bad\n\n  defines function\n\n    ExceptionFactory() as pure abstract\n      -> reason as String\n      <- builtException as Exception?\n\n    StandardExceptionFactory() is ExceptionFactory as pure\n      -> reason as String\n      <- builtException as Exception: Exception(reason)\n\n    getExceptionFactory()\n      -> factoryKind as String\n      <- chosenFactory as ExceptionFactory: StandardExceptionFactory\n      if factoryKind == \"alt\"\n        chosenFactory: StandardExceptionFactory\n\n    //Throw of a nested call: the factory selection step is hidden inside the throw\n    badThrowNestedCall()\n      stdout <- Stdout()\n      try\n        throw getExceptionFactory(\"std\")(\"oops\")\n      catch\n        -> caught as Exception\n        stdout.println(caught.reason())","expectedOutput":null,"kind":"bad","errors":["E11070"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11070/good.ek9","url":"https://ek9.io/errors/E11070.html","title":"Build the message first, then throw","code":"#!ek9\ndefines module error.e11070.good\n\n  defines function\n\n    ExceptionFactory() as pure abstract\n      -> reason as String\n      <- builtException as Exception?\n\n    StandardExceptionFactory() is ExceptionFactory as pure\n      -> reason as String\n      <- builtException as Exception: Exception(reason)\n\n    getExceptionFactory()\n      -> factoryKind as String\n      <- chosenFactory as ExceptionFactory: StandardExceptionFactory\n      if factoryKind == \"alt\"\n        chosenFactory: StandardExceptionFactory\n\n    //Form 1: direct constructor call - construction and throw on one line, no factory hidden\n    throwDirectConstructor()\n      stdout <- Stdout()\n      try\n        throw Exception(\"direct construction\")\n      catch\n        -> caught as Exception\n        stdout.println(caught.reason())\n\n    //Form 2: extract intermediate variable, then throw - factory selection visible\n    throwExtractedVariable()\n      stdout <- Stdout()\n      try\n        factory <- getExceptionFactory(\"std\")\n        ex <- factory(\"oops\")\n        throw ex\n      catch\n        -> caught as Exception\n        stdout.println(caught.reason())","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11070"}
{"id":"errors/E11080/bad.ek9","url":"https://ek9.io/errors/E11080.html","title":"E11080: hardcoded cloud provider credential detected","code":"#!ek9\ndefines module error.e11080.bad\n\n  defines function\n\n    <?-\n      AWS IAM User Access Key (AKIA prefix).\n    -?>\n    testAwsIamUserKey()\n      key <- \"AKIAIOSFODNN7EXAMPLE1\"\n\n      stdout <- Stdout()\n      stdout.println(key)\n\n    <?-\n      AWS STS Temporary Session Key (ASIA prefix).\n    -?>\n    testAwsSessionKey()\n      key <- \"ASIAISAMPLEKEYID12345\"\n\n      stdout <- Stdout()\n      stdout.println(key)\n\n    <?-\n      AWS Group Access Key (AGPA prefix).\n    -?>\n    testAwsGroupKey()\n      key <- \"AGPAFAKEEXAMPLE123456\"\n\n      stdout <- Stdout()\n      stdout.println(key)\n\n    <?-\n      AWS Instance Profile Access Key (AIPA prefix).\n    -?>\n    testAwsInstanceProfileKey()\n      key <- \"AIPAFAKEEXAMPLE123456\"\n\n      stdout <- Stdout()\n      stdout.println(key)\n\n    <?-\n      AWS Role Access Key (AROA prefix).\n    -?>\n    testAwsRoleKey()\n      key <- \"AROAFAKEEXAMPLE123456\"\n\n      stdout <- Stdout()\n      stdout.println(key)\n\n    <?-\n      AWS A3T variant Access Key.\n    -?>\n    testAwsA3tKey()\n      key <- \"A3T0FAKEEXAMPLE12345\"\n\n      stdout <- Stdout()\n      stdout.println(key)\n\n    <?-\n      GCP API Key (AIza prefix).\n    -?>\n    testGcpApiKey()\n      key <- \"AIzaSyC_abcDEFghijKLMNOpqrstuvwxyz123456\"\n\n      stdout <- Stdout()\n      stdout.println(key)\n\n    <?-\n      GCP OAuth Client ID.\n    -?>\n    testGcpOAuthClientId()\n      key <- \"123456789012-abcdefghijklmnopqrstuvwxyz012345.apps.googleusercontent.com\"\n\n      stdout <- Stdout()\n      stdout.println(key)\n\n    <?-\n      Azure Storage Connection String.\n    -?>\n    testAzureConnectionString()\n      key <- \"DefaultEndpointsProtocol=https;AccountName=mystorageacct;AccountKey=abc123\"\n\n      stdout <- Stdout()\n      stdout.println(key)\n\n    <?-\n      Azure Storage Account Key.\n    -?>\n    testAzureAccountKey()\n      key <- \"AccountKey=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVab==\"\n\n      stdout <- Stdout()\n      stdout.println(key)","expectedOutput":null,"kind":"bad","errors":["E11080"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11080/good.ek9","url":"https://ek9.io/errors/E11080.html","title":"Read the credential from the environment as a Sensitive","code":"#!ek9\ndefines module error.e11080.good\n\n  defines function\n\n    configureService()\n      -> credential as Sensitive\n      stdout <- Stdout()\n      stdout.println($(credential?))\n\n    demo()\n      secret <- EnvVars().sensitiveGet(\"AWS_ACCESS_KEY_ID\")\n      if secret?\n        configureService(secret)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11080"}
{"id":"errors/E11081/bad.ek9","url":"https://ek9.io/errors/E11081.html","title":"E11081: hardcoded platform token detected","code":"#!ek9\ndefines module error.e11081.bad\n\n  defines function\n\n    demo()\n      stdout <- Stdout()\n      token <- \"ghp_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghij\"\n      stdout.println(token)","expectedOutput":null,"kind":"bad","errors":["E11081"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11081/good.ek9","url":"https://ek9.io/errors/E11081.html","title":"Read the token from the environment as a Sensitive","code":"#!ek9\ndefines module error.e11081.good\n\n  defines function\n\n    configureService()\n      -> token as Sensitive\n      stdout <- Stdout()\n      stdout.println($(token?))\n\n    demo()\n      secret <- EnvVars().sensitiveGet(\"GITHUB_TOKEN\")\n      if secret?\n        configureService(secret)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11081"}
{"id":"errors/E11082/bad.ek9","url":"https://ek9.io/errors/E11082.html","title":"E11082: hardcoded private key material detected","code":"#!ek9\ndefines module error.e11082.bad\n\n  defines function\n\n    <?-\n      RSA private key PEM header detected.\n    -?>\n    testRsaPrivateKey()\n      key <- \"-----BEGIN RSA PRIVATE KEY-----\"\n\n      stdout <- Stdout()\n      stdout.println(key)\n\n    <?-\n      EC (Elliptic Curve) private key PEM header detected.\n    -?>\n    testEcPrivateKey()\n      key <- \"-----BEGIN EC PRIVATE KEY-----\"\n\n      stdout <- Stdout()\n      stdout.println(key)\n\n    <?-\n      DSA private key PEM header detected.\n    -?>\n    testDsaPrivateKey()\n      key <- \"-----BEGIN DSA PRIVATE KEY-----\"\n\n      stdout <- Stdout()\n      stdout.println(key)\n\n    <?-\n      PKCS8 generic private key PEM header detected.\n    -?>\n    testPkcs8PrivateKey()\n      key <- \"-----BEGIN PRIVATE KEY-----\"\n\n      stdout <- Stdout()\n      stdout.println(key)\n\n    <?-\n      Encrypted private key PEM header detected.\n    -?>\n    testEncryptedPrivateKey()\n      key <- \"-----BEGIN ENCRYPTED PRIVATE KEY-----\"\n\n      stdout <- Stdout()\n      stdout.println(key)\n\n    <?-\n      OpenSSH private key header detected.\n    -?>\n    testOpensshPrivateKey()\n      key <- \"-----BEGIN OPENSSH PRIVATE KEY-----\"\n\n      stdout <- Stdout()\n      stdout.println(key)","expectedOutput":null,"kind":"bad","errors":["E11082"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11082/good.ek9","url":"https://ek9.io/errors/E11082.html","title":"Load the key at run time as a Sensitive, never as a literal","code":"#!ek9\ndefines module error.e11082.good\n\n  defines function\n\n    configureService()\n      -> privateKey as Sensitive\n      stdout <- Stdout()\n      stdout.println($(privateKey?))\n\n    demo()\n      secret <- EnvVars().sensitiveGet(\"SERVICE_PRIVATE_KEY\")\n      if secret?\n        configureService(secret)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11082"}
{"id":"errors/E11083/bad.ek9","url":"https://ek9.io/errors/E11083.html","title":"E11083: hardcoded database credential detected","code":"#!ek9\ndefines module error.e11083.bad\n\n  defines function\n\n    <?-\n      PostgreSQL URL with embedded password detected.\n    -?>\n    testPostgresUrl()\n      dbUrl <- \"postgres://admin:s3cretPass@db.example.com:5432/mydb\"\n\n      stdout <- Stdout()\n      stdout.println(dbUrl)\n\n    <?-\n      MySQL URL with embedded password detected.\n    -?>\n    testMysqlUrl()\n      dbUrl <- \"mysql://root:hunter2@mysql.internal:3306/app\"\n\n      stdout <- Stdout()\n      stdout.println(dbUrl)\n\n    <?-\n      MongoDB URL with embedded password detected.\n    -?>\n    testMongoUrl()\n      dbUrl <- \"mongodb://appuser:mongopass@cluster0.abc.mongodb.net/mydb\"\n\n      stdout <- Stdout()\n      stdout.println(dbUrl)\n\n    <?-\n      MongoDB+SRV URL with embedded password detected.\n    -?>\n    testMongoSrvUrl()\n      dbUrl <- \"mongodb+srv://admin:secretpw@cluster.mongodb.net/db\"\n\n      stdout <- Stdout()\n      stdout.println(dbUrl)\n\n    <?-\n      Redis URL with embedded password detected.\n    -?>\n    testRedisUrl()\n      dbUrl <- \"redis://:redisPassword@redis.example.com:6379\"\n\n      stdout <- Stdout()\n      stdout.println(dbUrl)\n\n    <?-\n      JDBC URL with password parameter detected.\n    -?>\n    testJdbcUrl()\n      dbUrl <- \"jdbc:postgresql://localhost:5432/db?user=admin&password=secret123\"\n\n      stdout <- Stdout()\n      stdout.println(dbUrl)","expectedOutput":null,"kind":"bad","errors":["E11083"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11083/good.ek9","url":"https://ek9.io/errors/E11083.html","title":"Read the connection URL from the environment as a Sensitive","code":"#!ek9\ndefines module error.e11083.good\n\n  defines function\n\n    configureService()\n      -> databaseUrl as Sensitive\n      stdout <- Stdout()\n      stdout.println($(databaseUrl?))\n\n    demo()\n      secret <- EnvVars().sensitiveGet(\"DATABASE_URL\")\n      if secret?\n        configureService(secret)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11083"}
{"id":"errors/E11084/bad.ek9","url":"https://ek9.io/errors/E11084.html","title":"E11084: hardcoded JWT token detected","code":"#!ek9\ndefines module error.e11084.bad\n\n  defines function\n\n    <?-\n      Standard JWT token detected — eyJ header.payload.signature format.\n    -?>\n    testStandardJwt()\n      token <- \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c\"\n\n      stdout <- Stdout()\n      stdout.println(token)\n\n    <?-\n      Another JWT with different claims.\n    -?>\n    testAnotherJwt()\n      authHeader <- \"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiYXVkIjoiYXBwIn0.signature_part_here\"\n\n      stdout <- Stdout()\n      stdout.println(authHeader)","expectedOutput":null,"kind":"bad","errors":["E11084"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11084/good.ek9","url":"https://ek9.io/errors/E11084.html","title":"Obtain the token at run time as a Sensitive","code":"#!ek9\ndefines module error.e11084.good\n\n  defines function\n\n    configureService()\n      -> token as Sensitive\n      stdout <- Stdout()\n      stdout.println($(token?))\n\n    demo()\n      secret <- EnvVars().sensitiveGet(\"SESSION_TOKEN\")\n      if secret?\n        configureService(secret)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11084"}
{"id":"errors/E11086/bad.ek9","url":"https://ek9.io/errors/E11086.html","title":"E11086: hardcoded API key detected","code":"#!ek9\ndefines module error.e11086.bad\n\n  defines function\n\n    demo()\n      stdout <- Stdout()\n      key <- \"sk_live_abcdefghijklmnopqrstuvwxyz\"\n      stdout.println(key)","expectedOutput":null,"kind":"bad","errors":["E11086"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11086/good.ek9","url":"https://ek9.io/errors/E11086.html","title":"Read the API key from the environment as a Sensitive","code":"#!ek9\ndefines module error.e11086.good\n\n  defines function\n\n    configureService()\n      -> apiKey as Sensitive\n      stdout <- Stdout()\n      stdout.println($(apiKey?))\n\n    demo()\n      secret <- EnvVars().sensitiveGet(\"PAYMENT_API_KEY\")\n      if secret?\n        configureService(secret)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11086"}
{"id":"errors/E11090/bad.ek9","url":"https://ek9.io/errors/E11090.html","title":"E11090: reveal() on Sensitive is only permitted in a method of a class or trait that is Privileged: it has the Privileged trait, a trait that has it, or a super class that has it","code":"#!ek9\ndefines module error.e11090.bad\n\n  defines trait\n\n    Connector\n      connectWithSecret() as abstract\n        -> secret as Sensitive\n\n    Extractor\n      extract() as abstract\n        <- result as String?\n\n  defines class\n\n    <?-\n      Regular class without Privileged trait cannot call reveal().\n    -?>\n    UnprivilegedService with trait of Connector\n\n      override connectWithSecret()\n        -> secret as Sensitive\n\n        rawSecret <- secret.reveal()\n        stdout <- Stdout()\n        if rawSecret?\n          stdout.println(rawSecret)\n\n    <?-\n      Another class without Privileged calling reveal() on a local variable.\n    -?>\n    AnotherUnprivileged\n\n      processSecret()\n        -> credential as Sensitive\n\n        exposed <- credential.reveal()\n        stdout <- Stdout()\n        if exposed?\n          stdout.println(exposed)\n\n  defines function\n\n    <?-\n      Named dynamic class without Privileged trait cannot call reveal().\n    -?>\n    namedDynamicClassBadReveal()\n      -> secret as Sensitive\n      <- result as String?\n\n      handler <- BadExtractor(secret) as class\n        extract()\n          <- rtn as String?\n          rtn: secret.reveal()\n        default operator ?\n\n      if handler?\n        result: handler.extract()\n      else\n        result: \"no handler\"\n\n    <?-\n      Unnamed dynamic class with non-Privileged trait cannot call reveal().\n    -?>\n    unnamedDynamicClassBadReveal()\n      -> secret as Sensitive\n      <- result as String?\n\n      handler <- (secret) trait of Extractor as class\n        override extract()\n          <- rtn as String?\n          rtn: secret.reveal()\n        default operator ?\n\n      if handler?\n        result: handler.extract()\n      else\n        result: \"no handler\"\n\n    <?-\n      Standalone function cannot call reveal() because functions cannot have traits.\n    -?>\n    attemptRevealInFunction()\n      -> secret as Sensitive\n      <- result as String?\n\n      result: secret.reveal()\n\n    <?-\n      A valid function that does NOT call reveal() - should compile fine.\n    -?>\n    safeFunction()\n      -> secret as Sensitive\n      <- status as String?\n\n      if secret?\n        status: `Secret present (redacted: ${$secret})`\n      else\n        status: \"No secret available\"","expectedOutput":null,"kind":"bad","errors":["E11090"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E11090/good.ek9","url":"https://ek9.io/errors/E11090.html","title":"Reveal only in a Privileged class (the trait, or inherited from a trait or super class); elsewhere handle the Sensitive as it is","code":"#!ek9\ndefines module error.e11090.good\n\n  defines class\n\n    HttpClient with trait of Privileged\n      sendAuthenticatedRequest()\n        -> token as Sensitive\n        rawToken <- token.reveal()\n        stdout <- Stdout()\n        if rawToken?\n          header <- `Bearer ${rawToken}`\n          stdout.println(`Auth header set: ${length header} chars`)\n\n      default operator ?\n\n    SafeLogger\n      logActivity()\n        -> credential as Sensitive\n        stdout <- Stdout()\n        stdout.println(`Activity with credential: ${credential}`)\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11090"}
{"id":"errors/E11090/good_delegate.ek9","url":"https://ek9.io/errors/E11090.html","title":"A function cannot be Privileged: it hands the Sensitive value to a Privileged class","code":"#!ek9\ndefines module error.e11090.good.delegate\n\n  defines class\n    HttpClient with trait of Privileged\n      sendRequest()\n        -> apiKey as Sensitive\n        rawKey <- apiKey.reveal()\n        stdout <- Stdout()\n        if rawKey?\n          stdout.println(`Key of ${length rawKey} chars sent`)\n      default operator ?\n\n  defines function\n    doRequest()\n      -> apiKey as Sensitive\n      client <- HttpClient()\n      client.sendRequest(apiKey)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E11090"}
{"id":"errors/E12010/bad.ek9","url":"https://ek9.io/errors/E12010.html","title":"E12010: type requires declared package capability","code":"#!ek9\ndefines module error.e12010.bad\n\n  defines package\n    version <- 1.0.0-0\n    description <- \"Test publishable package with incomplete capabilities\"\n    license <- \"MIT\"\n    publicAccess <- true\n    capabilities <- [\"org.ek9.lang::TCP\"]\n\n  defines function\n\n    <?-\n      Using Stdout in a publishable package without the Stdout capability declared.\n      Only TCP is declared, so Stdout is not covered.\n    -?>\n    printMessage()\n      stdout <- Stdout()\n      stdout.println(\"Hello\")\n\n    <?-\n      Using Stderr in a publishable package without the Stderr capability declared.\n    -?>\n    logError()\n      stderr <- Stderr()\n      stderr.println(\"Error occurred\")\n\n    <?-\n      A function that does not use any gated types - should compile fine.\n    -?>\n    pureComputation()\n      <- result as Integer?\n      result: 42","expectedOutput":null,"kind":"bad","errors":["E12010"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E12010/good.ek9","url":"https://ek9.io/errors/E12010.html","title":"Declare every capability the package uses","code":"#!ek9\ndefines module error.e12010.good\n\n  defines package\n    version <- 1.0.0-0\n    description <- \"Test publishable package with complete capabilities\"\n    license <- \"MIT\"\n    publicAccess <- true\n    capabilities <- [\"org.ek9.lang::Stderr\", \"org.ek9.lang::Stdout\"]\n\n  defines function\n\n    printMessage()\n      stdout <- Stdout()\n      stdout.println(\"Hello\")\n\n    logError()\n      stderr <- Stderr()\n      stderr.println(\"Error occurred\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E12010"}
{"id":"errors/E12020/bad.ek9","url":"https://ek9.io/errors/E12020.html","title":"E12020: application registers services but program has no HTTP server","code":"#!ek9\ndefines module error.e12020.bad\n\n  defines constant\n\n    plainText <- \"text/plain\"\n\n  defines service\n\n    StatusService for :/status open\n\n      health() as GET for :/health\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"ok\")\n          override contentType() as pure\n            <- rtn as String: plainText\n          default operator ?\n\n  defines application\n\n    StatusApp\n      register StatusService()\n\n  defines program\n\n    ServicesWithoutHttpDemo() with application of StatusApp\n      stdout <- Stdout()\n      stdout.println(\"this program exits — StatusService can never be reached\")","expectedOutput":null,"kind":"bad","errors":["E12020"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E12020/good.ek9","url":"https://ek9.io/errors/E12020.html","title":"Serve the registered services over HTTP","code":"#!ek9\ndefines module error.e12020.good\n\n  defines service\n\n    StatusService for :/status open\n\n      health() as GET for :/status\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"ok\")\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          default operator ?\n\n  defines application\n\n    StatusApp\n      register StatusService()\n\n  defines program\n\n    ServicesWithHttpDemo() with application of StatusApp\n      props <- NetworkProperties(9090)\n      HTTP(props).serve()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E12020"}
{"id":"errors/E12020/good_split.ek9","url":"https://ek9.io/errors/E12020.html","title":"Or give a program that does not serve an application with no services","code":"#!ek9\ndefines module error.e12020.good.split\n\n  defines component\n\n    Repository as abstract\n      size() as abstract\n        <- rtn as Integer?\n      default operator ?\n\n    InMemoryRepository is Repository\n      override size()\n        <- rtn as Integer: 0\n      default operator ?\n\n  defines service\n\n    StatusService for :/status open\n\n      health() as GET for :/status\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"ok\")\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          default operator ?\n\n  defines application\n\n    StatusApp\n      register InMemoryRepository() as Repository\n      register StatusService()\n\n    RepositoryOnly\n      register InMemoryRepository() as Repository\n\n  defines program\n\n    Report() with application of RepositoryOnly\n      stdout <- Stdout()\n      repository as Repository!\n      stdout.println($repository.size())","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E12020"}
{"id":"errors/E12021/bad.ek9","url":"https://ek9.io/errors/E12021.html","title":"E12021: program creates HTTP but application has no service registrations","code":"#!ek9\ndefines module error.e12021.bad\n\n  defines component\n\n    Logger as abstract\n      doLog()\n        <- rtn as String: \"logged\"\n      default operator ?\n\n    ConsoleLogger extends Logger\n      default operator ?\n\n  defines application\n\n    LogApp\n      register ConsoleLogger() as Logger\n\n  defines program\n\n    HttpWithoutServicesDemo() with application of LogApp\n      props <- NetworkProperties(9090)\n      HTTP(props).serve()","expectedOutput":null,"kind":"bad","errors":["E12021"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E12021/good.ek9","url":"https://ek9.io/errors/E12021.html","title":"Register a service in the application the HTTP server serves","code":"#!ek9\ndefines module error.e12021.good\n\n  defines service\n\n    HelloService for :/api open\n\n      health() as GET for :/status\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"ok\")\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          default operator ?\n\n  defines application\n\n    HelloApp\n      register HelloService()\n\n  defines program\n\n    HttpWithServicesDemo() with application of HelloApp\n      props <- NetworkProperties(9090)\n      HTTP(props).serve()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E12021"}
{"id":"errors/E12022/bad.ek9","url":"https://ek9.io/errors/E12022.html","title":"E12022: program creates HTTP without 'with application of' linkage","code":"#!ek9\ndefines module error.e12022.bad\n\n  defines program\n\n    HttpWithoutAppDemo()\n      props <- NetworkProperties(9090)\n      HTTP(props).serve()","expectedOutput":null,"kind":"bad","errors":["E12022"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E12022/good.ek9","url":"https://ek9.io/errors/E12022.html","title":"Link the program to an application with services","code":"#!ek9\ndefines module error.e12022.good\n\n  defines service\n\n    HelloService for :/api open\n\n      health() as GET for :/status\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"ok\")\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          default operator ?\n\n  defines application\n\n    HelloApp\n      register HelloService()\n\n  defines program\n\n    HttpWithAppDemo() with application of HelloApp\n      props <- NetworkProperties(9090)\n      HTTP(props).serve()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E12022"}
{"id":"errors/E12023/bad.ek9","url":"https://ek9.io/errors/E12023.html","title":"E12023: program creates more than one HTTP instance","code":"#!ek9\ndefines module error.e12023.bad\n\n  defines service\n\n    HelloService for :/api open\n      health() as GET for :/status\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"ok\")\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          default operator ?\n\n  defines application\n\n    HelloApp\n      register HelloService()\n\n  defines program\n\n    DuplicateHttpDemo() with application of HelloApp\n      props <- NetworkProperties(9090)\n      HTTP(props).serve()\n      HTTP(props).serve()","expectedOutput":null,"kind":"bad","errors":["E12023"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E12023/good.ek9","url":"https://ek9.io/errors/E12023.html","title":"Create one HTTP server - it serves every registered service","code":"#!ek9\ndefines module error.e12023.good\n\n  defines service\n\n    HelloService for :/api open\n\n      health() as GET for :/status\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"ok\")\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          default operator ?\n\n  defines application\n\n    HelloApp\n      register HelloService()\n\n  defines program\n\n    SingleHttpDemo() with application of HelloApp\n      props <- NetworkProperties(9090)\n      HTTP(props).serve()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E12023"}
{"id":"errors/E12023/good_split.ek9","url":"https://ek9.io/errors/E12023.html","title":"Servers on different ports: separate programs, each with its own application","code":"#!ek9\ndefines module error.e12023.good.split\n\n  defines service\n\n    PublicService for :/api open\n\n      health() as GET for :/status\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"ok\")\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          default operator ?\n\n    AdminService for :/admin open\n\n      health() as GET for :/status\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"admin ok\")\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          default operator ?\n\n  defines application\n\n    PublicApp\n      register PublicService()\n\n    AdminApp\n      register AdminService()\n\n  defines program\n\n    PublicServer() with application of PublicApp\n      HTTP(NetworkProperties(8080)).serve()\n\n    AdminServer() with application of AdminApp\n      HTTP(NetworkProperties(9090)).serve()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E12023"}
{"id":"errors/E12050/bad.ek9","url":"https://ek9.io/errors/E12050.html","title":"E12050: service requires 'open' or 'constrain by' security posture declaration","code":"#!ek9\ndefines module error.e12050.bad\n\n  defines service\n\n    NoPostureService for :/api\n      health() as GET for :/status\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"ok\")\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          default operator ?","expectedOutput":null,"kind":"bad","errors":["E12050"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E12050/good.ek9","url":"https://ek9.io/errors/E12050.html","title":"Declare the posture: 'open', or 'constrain by' a gate","code":"#!ek9\ndefines module error.e12050.good\n\n  defines service\n\n    PostureService for :/api open\n\n      health() as GET for :/status\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"ok\")\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E12050"}
{"id":"errors/E12050/good_operation.ek9","url":"https://ek9.io/errors/E12050.html","title":"Or declare the posture on each operation","code":"#!ek9\ndefines module error.e12050.good.operation\n\n  defines function\n\n    ApiGate is SecurityGate\n      -> context as HTTPContext\n      <- rtn as HTTPContext: context\n\n  defines service\n\n    PostureService for :/api\n      health() as GET for :/status open\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"ok\")\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          default operator ?\n\n      report() as GET for :/report constrain by ApiGate\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"report\")\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E12050"}
{"id":"errors/E12060/bad.ek9","url":"https://ek9.io/errors/E12060.html","title":"E12060: constraint reference could not be resolved to a type","code":"#!ek9\ndefines module error.e12060.bad\n\n  defines service\n\n    UnresolvedConstraint for :/api constrain by NonExistentGate\n      health() as GET for :/status\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"ok\")\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          default operator ?","expectedOutput":null,"kind":"bad","errors":["E12060"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E12060/good.ek9","url":"https://ek9.io/errors/E12060.html","title":"Constrain by a SecurityGate that exists","code":"#!ek9\ndefines module error.e12060.good\n\n  defines function\n\n    ApiGate is SecurityGate\n      -> context as HTTPContext\n      <- rtn as HTTPContext: context\n\n  defines service\n\n    GatedService for :/api constrain by ApiGate\n\n      health() as GET for :/status\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"ok\")\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E12060"}
{"id":"errors/E12062/bad.ek9","url":"https://ek9.io/errors/E12062.html","title":"E12062: constraint reference must extend SecurityGate or CORSPolicy","code":"#!ek9\ndefines module error.e12062.bad\n\n  defines function\n\n    NotAGate() as pure\n      <- rtn as String: \"not a security gate\"\n\n  defines service\n\n    InvalidConstraint for :/api constrain by NotAGate\n      health() as GET for :/status\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"ok\")\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          default operator ?","expectedOutput":null,"kind":"bad","errors":["E12062"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E12062/good.ek9","url":"https://ek9.io/errors/E12062.html","title":"Constrain by a function that is a SecurityGate","code":"#!ek9\ndefines module error.e12062.good\n\n  defines function\n\n    ApiGate is SecurityGate\n      -> context as HTTPContext\n      <- rtn as HTTPContext: context\n\n  defines service\n\n    GatedService for :/api constrain by ApiGate\n\n      health() as GET for :/status\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"ok\")\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E12062"}
{"id":"errors/E12064/bad.ek9","url":"https://ek9.io/errors/E12064.html","title":"E12064: both constraint references extend the same base type","code":"#!ek9\ndefines module error.e12064.bad\n\n  defines function\n\n    GateAlpha is SecurityGate\n      -> context as HTTPContext\n      <- rtn as HTTPContext: context\n\n    GateBeta is SecurityGate\n      -> context as HTTPContext\n      <- rtn as HTTPContext: context\n\n  defines service\n\n    DuplicateRoleService for :/api constrain by GateAlpha and GateBeta\n      health() as GET for :/status\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"ok\")\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          default operator ?","expectedOutput":null,"kind":"bad","errors":["E12064"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E12064/good.ek9","url":"https://ek9.io/errors/E12064.html","title":"One SecurityGate (and at most one CORSPolicy) per service","code":"#!ek9\ndefines module error.e12064.good\n\n  defines function\n\n    ApiGate is SecurityGate\n      -> context as HTTPContext\n      <- rtn as HTTPContext: context\n\n  defines service\n\n    GatedService for :/api constrain by ApiGate\n\n      health() as GET for :/status\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"ok\")\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E12064"}
{"id":"errors/E12064/good_cors.ek9","url":"https://ek9.io/errors/E12064.html","title":"A SecurityGate and a CORSPolicy together are two roles, not a duplicate","code":"#!ek9\ndefines module error.e12064.good.cors\n\n  defines function\n\n    ApiGate is SecurityGate\n      -> context as HTTPContext\n      <- rtn as HTTPContext: context\n\n    AllowedOrigins is CORSPolicy\n      -> origin as String\n      <- rtn as Boolean: origin == \"https://ek9.io\"\n\n  defines service\n\n    GatedService for :/api constrain by ApiGate and AllowedOrigins\n\n      health() as GET for :/status\n        <- response as HTTPResponse: () with trait of HTTPResponse\n          override status() as pure\n            <- rtn as Integer: 200\n          override content()\n            <- rtn as Bytes: Bytes().withUtf8(\"ok\")\n          override contentType() as pure\n            <- rtn as String: \"text/plain\"\n          default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E12064"}
{"id":"errors/E50001/bad.ek9","url":"https://ek9.io/errors/E50001.html","title":"E50001: not resolved","code":"#!ek9\ndefines module error.e50001.bad\n\n  defines function\n\n    greeting()\n      -> customerName as String\n      <- message as String?\n      message: salutation + customerName","expectedOutput":null,"kind":"bad","errors":["E50001"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E50001/good.ek9","url":"https://ek9.io/errors/E50001.html","title":"Declare the name before you use it","code":"#!ek9\ndefines module error.e50001.good\n\n  defines function\n\n    greeting()\n      -> customerName as String\n      <- message as String?\n      salutation <- \"Hello, \"\n      message: salutation + customerName","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E50001"}
{"id":"errors/E50010/bad.ek9","url":"https://ek9.io/errors/E50010.html","title":"E50010: type not resolved","code":"#!ek9\ndefines module error.e50010.bad\n\n  defines function\n\n    describe()\n      <- rtn as String: \"unknown\"\n      item as Widget?\n      if item?\n        rtn: \"widget\"","expectedOutput":null,"kind":"bad","errors":["E50010"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E50010/good.ek9","url":"https://ek9.io/errors/E50010.html","title":"Declare the type, or use one that exists","code":"#!ek9\ndefines module error.e50010.good\n\n  defines record\n\n    Widget\n      label as String: \"widget\"\n\n      default operator ?\n\n  defines function\n\n    describe()\n      -> item as Widget\n      <- rtn as String: \"unknown\"\n      if item?\n        rtn: item.label","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E50010"}
{"id":"errors/E50020/bad.ek9","url":"https://ek9.io/errors/E50020.html","title":"E50020: incompatible genus","code":"#!ek9\ndefines module error.e50020.bad\n\n  defines function\n\n    greeting()\n      <- rtn as String: \"hello\"\n\n  defines class\n\n    Greeter extends greeting\n      describe()\n        <- rtn as String: \"greeter\"","expectedOutput":null,"kind":"bad","errors":["E50020"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E50020/good.ek9","url":"https://ek9.io/errors/E50020.html","title":"A class extends a class (a function extends a function)","code":"#!ek9\ndefines module error.e50020.good\n\n  defines class\n\n    Base as open\n      describe()\n        <- rtn as String: \"base\"\n\n    Greeter extends Base\n      override describe()\n        <- rtn as String: \"greeter\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E50020"}
{"id":"errors/E50030/bad.ek9","url":"https://ek9.io/errors/E50030.html","title":"E50030: types are not compatible with each other","code":"#!ek9\ndefines module error.e50030.bad\n\n  defines class\n    Base as open\n      id as Integer: 0\n      default operator\n    Leaf extends Base as open\n      default operator\n    Sibling extends Base as open\n      default operator\n\n  defines function\n\n    demo()\n      <- rtn as Integer?\n      text <- \"42\"\n      rtn: text\n\n    coalescing()\n      ->\n        count as Integer\n        text as String\n        letter as Character\n        pattern as RegEx\n        maybeCount as Optional of Integer\n      either <- count ?: text            //Integer and String share only 'Any'\n      shown <- letter ?: pattern         //both promote to String; neither IS one\n      known <- maybeCount ?: 0           //an 'Optional of Integer' is not an Integer\n\n    literals()\n      mixed <- [1, \"two\"]                //Integer and String share only 'Any'\n      byName <- {\"count\": 1, \"name\": \"two\"}\n\n    copies()\n      ->\n        leaf as Leaf\n        sibling as Sibling\n      leaf :=: sibling                   //no object is both a Leaf and a Sibling","expectedOutput":null,"kind":"bad","errors":["E50030"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E50030/good.ek9","url":"https://ek9.io/errors/E50030.html","title":"Convert explicitly","code":"#!ek9\ndefines module error.e50030.good\n\n  defines function\n\n    demo()\n      <- rtn as Integer?\n      text <- \"42\"\n      rtn: Integer(text)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E50030"}
{"id":"errors/E50030/good_forms.ek9","url":"https://ek9.io/errors/E50030.html","title":"Give the operands a type they share, or declare the type a literal holds","code":"#!ek9\ndefines module error.e50030.good.forms\n\n  defines function\n\n    coalescing()\n      ->\n        count as Integer\n        amount as Float\n        text as String\n        letter as Character\n        pattern as RegEx\n        maybeCount as Optional of Integer\n      <- rtn as String?\n      //Integer promotes to Float: the result is a Float\n      measure <- count ?: amount\n      //Convert one operand explicitly\n      either <- $count ?: text\n      //A List literal takes the one type every element promotes to: a List of String\n      shapes <- [letter, pattern]\n      //An Optional supplies its own default\n      known <- maybeCount.getOrDefault(0)\n      rtn: `${measure} ${either} ${shapes} ${known}`\n\n    literals()\n      <- rtn as String?\n      //A declared target supplies the element type\n      mixed as List of Any: [1, \"two\"]\n      byName as Dict of (String, Any): {\"count\": 1, \"name\": \"two\"}\n      rtn: `${length mixed} ${length byName}`","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E50030"}
{"id":"errors/E50040/bad.ek9","url":"https://ek9.io/errors/E50040.html","title":"E50040: cannot be abstract","code":"#!ek9\ndefines module error.e50040.bad\n\n  defines class\n\n    Shape\n      area() as abstract\n        <- rtn as Float?","expectedOutput":null,"kind":"bad","errors":["E50040"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E50040/good.ek9","url":"https://ek9.io/errors/E50040.html","title":"Only an open or abstract type may have an abstract method","code":"#!ek9\ndefines module error.e50040.good\n\n  defines class\n\n    Shape as abstract\n      area() as abstract\n        <- rtn as Float?\n\n    Square extends Shape\n      side as Float: 1.0\n\n      override area()\n        <- rtn as Float: side * side\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E50040"}
{"id":"errors/E50050/bad.ek9","url":"https://ek9.io/errors/E50050.html","title":"E50050: Variable/Constant duplicated","code":"#!ek9\ndefines module error.e50050.bad\n\n  defines function\n\n    demo()\n      <- rtn as Integer?\n      total <- 42\n      total <- 100\n      rtn: total","expectedOutput":null,"kind":"bad","errors":["E50050"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E50050/good.ek9","url":"https://ek9.io/errors/E50050.html","title":"Assign the existing variable with :=","code":"#!ek9\ndefines module error.e50050.good\n\n  defines function\n\n    demo()\n      <- rtn as Integer?\n      total <- 42\n      total := total + 100\n      rtn: total","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E50050"}
{"id":"errors/E50050/good_new_name.ek9","url":"https://ek9.io/errors/E50050.html","title":"Or give the second value its own name","code":"#!ek9\ndefines module error.e50050.good.new.name\n\n  defines function\n\n    demo()\n      <- rtn as Integer?\n      first <- 42\n      second <- 100\n      rtn: first + second","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E50050"}
{"id":"errors/E50060/bad.ek9","url":"https://ek9.io/errors/E50060.html","title":"E50060: method/function not resolved","code":"#!ek9\ndefines module error.e50060.bad\n\n  defines class\n\n    Counter\n      describe()\n        -> count as Integer\n        <- rtn as String: $count\n\n  defines function\n\n    demo()\n      <- rtn as String?\n      counter <- Counter()\n      rtn: counter.describeAll()","expectedOutput":null,"kind":"bad","errors":["E50060"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E50060/good.ek9","url":"https://ek9.io/errors/E50060.html","title":"Call a method that exists, with the arguments it declares","code":"#!ek9\ndefines module error.e50060.good\n\n  defines class\n\n    Counter\n      describe()\n        -> count as Integer\n        <- rtn as String: $count\n\n  defines function\n\n    demo()\n      <- rtn as String?\n      counter <- Counter()\n      rtn: counter.describe(42)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E50060"}
{"id":"errors/E50070/bad.ek9","url":"https://ek9.io/errors/E50070.html","title":"E50070: cannot use an abstract function in this manner","code":"#!ek9\ndefines module error.e50070.bad\n\n  defines function\n\n    Processor() as abstract\n      -> input as String\n      <- output as String?\n\n    demo()\n      <- rtn as String?\n      processor as Processor: Processor\n      rtn: processor(\"test\")","expectedOutput":null,"kind":"bad","errors":["E50070"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E50070/good.ek9","url":"https://ek9.io/errors/E50070.html","title":"Use a concrete function that is a Processor","code":"#!ek9\ndefines module error.e50070.good\n\n  defines function\n\n    Processor() as abstract\n      -> input as String\n      <- output as String?\n\n    UpperCaseProcessor() is Processor\n      -> input as String\n      <- output as String: input.upperCase()\n\n    demo()\n      <- rtn as String?\n      processor as Processor: UpperCaseProcessor\n      rtn: processor(\"test\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E50070"}
{"id":"errors/E50080/bad.ek9","url":"https://ek9.io/errors/E50080.html","title":"E50080: cannot make a call on an abstract function/type directly","code":"#!ek9\ndefines module error.e50080.bad\n\n  defines class\n\n    Shape as abstract\n      area() as abstract\n        <- rtn as Float?\n\n  defines function\n\n    demo()\n      <- rtn as Float?\n      shape <- Shape()\n      rtn: shape.area()","expectedOutput":null,"kind":"bad","errors":["E50080"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E50080/good.ek9","url":"https://ek9.io/errors/E50080.html","title":"Construct a concrete subtype","code":"#!ek9\ndefines module error.e50080.good\n\n  defines class\n\n    Shape as abstract\n      area() as abstract\n        <- rtn as Float?\n\n    Circle extends Shape\n      radius as Float: 5.0\n\n      override area()\n        <- rtn as Float: radius * radius\n\n      default operator ?\n\n  defines function\n\n    demo()\n      <- rtn as Float?\n      shape as Shape: Circle()\n      rtn: shape.area()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E50080"}
{"id":"errors/E50090/bad.ek9","url":"https://ek9.io/errors/E50090.html","title":"E50090: incompatible genus in parameter(s)","code":"#!ek9\ndefines module error.e50090.bad\n\n  defines record\n\n    Holder\n      count as Integer: 1\n\n      default operator ?\n\n  defines class\n\n    Router\n      route() as dispatcher\n        -> item as Integer\n        <- rtn as String: \"integer\"\n\n      route()\n        -> item as Holder\n        <- rtn as String: \"holder\"","expectedOutput":null,"kind":"bad","errors":["E50090"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E50090/good.ek9","url":"https://ek9.io/errors/E50090.html","title":"Give the dispatcher entry point a parameter every handler is compatible with","code":"#!ek9\ndefines module error.e50090.good\n\n  defines record\n\n    Holder\n      count as Integer: 1\n\n      default operator ?\n\n  defines class\n\n    Router\n      route() as dispatcher\n        -> item as Any\n        <- rtn as String: \"any\"\n\n      route()\n        -> item as Holder\n        <- rtn as String: \"holder\"","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E50090"}
{"id":"errors/E50100/bad.ek9","url":"https://ek9.io/errors/E50100.html","title":"E50100: incompatible category","code":"#!ek9\ndefines module error.e50100.bad\n\n  defines function\n\n    Transformer() of type (K, V) as abstract\n      -> item as K\n      <- rtn as V?\n\n    Shouter() extends Transformer\n      -> text as String\n      <- rtn as String: text.upperCase()","expectedOutput":null,"kind":"bad","errors":["E50100"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E50100/good.ek9","url":"https://ek9.io/errors/E50100.html","title":"Parameterise the generic - a dynamic function can be one","code":"#!ek9\ndefines module error.e50100.good\n\n  defines function\n\n    Transformer() of type (K, V) as abstract\n      -> item as K\n      <- rtn as V?\n\n    shouter()\n      <- rtn as Transformer of (String, String): () is Transformer of (String, String) as function\n        rtn: item.upperCase()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E50100"}
{"id":"errors/E81001/bad/greeting.ek9","url":"https://ek9.io/errors/E81001.html","title":"E81001: missing expected output file for test case","code":"#!ek9\ndefines module error.e81001.bad\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"bad","errors":["E81001"],"validation":"`ek9 -t greeting.ek9` in E81001/bad/ reports exactly E81001 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81001/bad/dev/tests.ek9","url":"https://ek9.io/errors/E81001.html","title":"E81001: missing expected output file for test case","code":"#!ek9\ndefines module error.e81001.bad.tests\n\n  references\n    error.e81001.bad::greeting\n\n  defines program\n\n    @Test\n    GreetingCases()\n      -> name as String\n      stdout <- Stdout()\n      greeted <- greeting(name)\n      stdout.println(greeted)\n      assert greeted == `Hello, ${name}`","expectedOutput":null,"kind":"bad","errors":["E81001"],"validation":"`ek9 -t greeting.ek9` in E81001/bad/ reports exactly E81001 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81001/good/greeting.ek9","url":"https://ek9.io/errors/E81001.html","title":"Each commandline_arg_simple.txt has its expected_case_simple.txt","code":"#!ek9\ndefines module error.e81001.good\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81001/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81001"}
{"id":"errors/E81001/good/dev/tests.ek9","url":"https://ek9.io/errors/E81001.html","title":"Each commandline_arg_simple.txt has its expected_case_simple.txt","code":"#!ek9\ndefines module error.e81001.good.tests\n\n  references\n    error.e81001.good::greeting\n\n  defines program\n\n    @Test\n    GreetingCases()\n      -> name as String\n      stdout <- Stdout()\n      greeted <- greeting(name)\n      stdout.println(greeted)\n      assert greeted == `Hello, ${name}`","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81001/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81001"}
{"id":"errors/E81002/bad/greeting.ek9","url":"https://ek9.io/errors/E81002.html","title":"E81002: orphan expected output file (no matching commandline args)","code":"#!ek9\ndefines module error.e81002.bad\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"bad","errors":["E81002"],"validation":"`ek9 -t greeting.ek9` in E81002/bad/ reports exactly E81002 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81002/bad/dev/tests.ek9","url":"https://ek9.io/errors/E81002.html","title":"E81002: orphan expected output file (no matching commandline args)","code":"#!ek9\ndefines module error.e81002.bad.tests\n\n  references\n    error.e81002.bad::greeting\n\n  defines program\n\n    @Test\n    GreetingCases()\n      -> name as String\n      stdout <- Stdout()\n      stdout.println(greeting(name))","expectedOutput":null,"kind":"bad","errors":["E81002"],"validation":"`ek9 -t greeting.ek9` in E81002/bad/ reports exactly E81002 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81002/good/greeting.ek9","url":"https://ek9.io/errors/E81002.html","title":"The orphan expected_case_other.txt gets its commandline_arg_other.txt","code":"#!ek9\ndefines module error.e81002.good\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81002/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81002"}
{"id":"errors/E81002/good/dev/tests.ek9","url":"https://ek9.io/errors/E81002.html","title":"The orphan expected_case_other.txt gets its commandline_arg_other.txt","code":"#!ek9\ndefines module error.e81002.good.tests\n\n  references\n    error.e81002.good::greeting\n\n  defines program\n\n    @Test\n    GreetingCases()\n      -> name as String\n      stdout <- Stdout()\n      stdout.println(greeting(name))","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81002/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81002"}
{"id":"errors/E81003/bad/greeting.ek9","url":"https://ek9.io/errors/E81003.html","title":"E81003: argument count mismatch between program and file","code":"#!ek9\ndefines module error.e81003.bad\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"bad","errors":["E81003"],"validation":"`ek9 -t greeting.ek9` in E81003/bad/ reports exactly E81003 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81003/bad/dev/tests.ek9","url":"https://ek9.io/errors/E81003.html","title":"E81003: argument count mismatch between program and file","code":"#!ek9\ndefines module error.e81003.bad.tests\n\n  references\n    error.e81003.bad::greeting\n\n  defines program\n\n    @Test\n    GreetingCases()\n      ->\n        name as String\n        times as Integer\n      stdout <- Stdout()\n      stdout.println(`${greeting(name)} (${times})`)","expectedOutput":null,"kind":"bad","errors":["E81003"],"validation":"`ek9 -t greeting.ek9` in E81003/bad/ reports exactly E81003 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81003/good/greeting.ek9","url":"https://ek9.io/errors/E81003.html","title":"commandline_arg_simple.txt holds one line per parameter","code":"#!ek9\ndefines module error.e81003.good\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81003/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81003"}
{"id":"errors/E81003/good/dev/tests.ek9","url":"https://ek9.io/errors/E81003.html","title":"commandline_arg_simple.txt holds one line per parameter","code":"#!ek9\ndefines module error.e81003.good.tests\n\n  references\n    error.e81003.good::greeting\n\n  defines program\n\n    @Test\n    GreetingCases()\n      ->\n        name as String\n        times as Integer\n      stdout <- Stdout()\n      stdout.println(`${greeting(name)} (${times})`)","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81003/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81003"}
{"id":"errors/E81004/bad/greeting.ek9","url":"https://ek9.io/errors/E81004.html","title":"E81004: arguments provided for no-parameter program","code":"#!ek9\ndefines module error.e81004.bad\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"bad","errors":["E81004"],"validation":"`ek9 -t greeting.ek9` in E81004/bad/ reports exactly E81004 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81004/bad/dev/tests.ek9","url":"https://ek9.io/errors/E81004.html","title":"E81004: arguments provided for no-parameter program","code":"#!ek9\ndefines module error.e81004.bad.tests\n\n  references\n    error.e81004.bad::greeting\n\n  defines program\n\n    @Test\n    GreetingOnce()\n      stdout <- Stdout()\n      stdout.println(greeting(\"EK9\"))","expectedOutput":null,"kind":"bad","errors":["E81004"],"validation":"`ek9 -t greeting.ek9` in E81004/bad/ reports exactly E81004 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81004/good/greeting.ek9","url":"https://ek9.io/errors/E81004.html","title":"A program that takes no arguments is checked by expected_output.txt","code":"#!ek9\ndefines module error.e81004.good\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81004/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81004"}
{"id":"errors/E81004/good/dev/tests.ek9","url":"https://ek9.io/errors/E81004.html","title":"A program that takes no arguments is checked by expected_output.txt","code":"#!ek9\ndefines module error.e81004.good.tests\n\n  references\n    error.e81004.good::greeting\n\n  defines program\n\n    @Test\n    GreetingOnce()\n      stdout <- Stdout()\n      stdout.println(greeting(\"EK9\"))","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81004/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81004"}
{"id":"errors/E81005/bad/greeting.ek9","url":"https://ek9.io/errors/E81005.html","title":"E81005: program requires arguments but no commandline files found","code":"#!ek9\ndefines module error.e81005.bad\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"bad","errors":["E81005"],"validation":"`ek9 -t greeting.ek9` in E81005/bad/ reports exactly E81005 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81005/bad/dev/tests.ek9","url":"https://ek9.io/errors/E81005.html","title":"E81005: program requires arguments but no commandline files found","code":"#!ek9\ndefines module error.e81005.bad.tests\n\n  references\n    error.e81005.bad::greeting\n\n  defines program\n\n    @Test\n    GreetingCases()\n      -> name as String\n      stdout <- Stdout()\n      greeted <- greeting(name)\n      stdout.println(greeted)\n      assert greeted == `Hello, ${name}`","expectedOutput":null,"kind":"bad","errors":["E81005"],"validation":"`ek9 -t greeting.ek9` in E81005/bad/ reports exactly E81005 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81005/good/greeting.ek9","url":"https://ek9.io/errors/E81005.html","title":"The program is given its argument by commandline_arg_simple.txt","code":"#!ek9\ndefines module error.e81005.good\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81005/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81005"}
{"id":"errors/E81005/good/dev/tests.ek9","url":"https://ek9.io/errors/E81005.html","title":"The program is given its argument by commandline_arg_simple.txt","code":"#!ek9\ndefines module error.e81005.good.tests\n\n  references\n    error.e81005.good::greeting\n\n  defines program\n\n    @Test\n    GreetingCases()\n      -> name as String\n      stdout <- Stdout()\n      greeted <- greeting(name)\n      stdout.println(greeted)\n      assert greeted == `Hello, ${name}`","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81005/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81005"}
{"id":"errors/E81006/bad/greeting.ek9","url":"https://ek9.io/errors/E81006.html","title":"E81006: cannot convert argument to required parameter type","code":"#!ek9\ndefines module error.e81006.bad\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"bad","errors":["E81006"],"validation":"`ek9 -t greeting.ek9` in E81006/bad/ reports exactly E81006 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81006/bad/dev/tests.ek9","url":"https://ek9.io/errors/E81006.html","title":"E81006: cannot convert argument to required parameter type","code":"#!ek9\ndefines module error.e81006.bad.tests\n\n  references\n    error.e81006.bad::greeting\n\n  defines program\n\n    @Test\n    GreetingCases()\n      -> times as Integer\n      stdout <- Stdout()\n      stdout.println(greeting(`${times}`))","expectedOutput":null,"kind":"bad","errors":["E81006"],"validation":"`ek9 -t greeting.ek9` in E81006/bad/ reports exactly E81006 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81006/good/greeting.ek9","url":"https://ek9.io/errors/E81006.html","title":"The argument is an Integer","code":"#!ek9\ndefines module error.e81006.good\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81006/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81006"}
{"id":"errors/E81006/good/dev/tests.ek9","url":"https://ek9.io/errors/E81006.html","title":"The argument is an Integer","code":"#!ek9\ndefines module error.e81006.good.tests\n\n  references\n    error.e81006.good::greeting\n\n  defines program\n\n    @Test\n    GreetingCases()\n      -> times as Integer\n      stdout <- Stdout()\n      stdout.println(greeting(`${times}`))","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81006/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81006"}
{"id":"errors/E81007/bad/greeting.ek9","url":"https://ek9.io/errors/E81007.html","title":"E81007: @Test program has no assertions and no expected output files","code":"#!ek9\ndefines module error.e81007.bad\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"bad","errors":["E81007"],"validation":"`ek9 -t greeting.ek9` in E81007/bad/ reports exactly E81007 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81007/bad/dev/tests.ek9","url":"https://ek9.io/errors/E81007.html","title":"E81007: @Test program has no assertions and no expected output files","code":"#!ek9\ndefines module error.e81007.bad.tests\n\n  references\n    error.e81007.bad::greeting\n\n  defines program\n\n    @Test\n    GreetingOnce()\n      stdout <- Stdout()\n      stdout.println(greeting(\"EK9\"))","expectedOutput":null,"kind":"bad","errors":["E81007"],"validation":"`ek9 -t greeting.ek9` in E81007/bad/ reports exactly E81007 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81007/good/greeting.ek9","url":"https://ek9.io/errors/E81007.html","title":"expected_output.txt says what the test must print","code":"#!ek9\ndefines module error.e81007.good\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81007/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81007"}
{"id":"errors/E81007/good/dev/tests.ek9","url":"https://ek9.io/errors/E81007.html","title":"expected_output.txt says what the test must print","code":"#!ek9\ndefines module error.e81007.good.tests\n\n  references\n    error.e81007.good::greeting\n\n  defines program\n\n    @Test\n    GreetingOnce()\n      stdout <- Stdout()\n      stdout.println(greeting(\"EK9\"))","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81007/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81007"}
{"id":"errors/E81010/bad/greeting.ek9","url":"https://ek9.io/errors/E81010.html","title":"E81010: invalid placeholder syntax in expected output","code":"#!ek9\ndefines module error.e81010.bad\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"bad","errors":["E81010"],"validation":"`ek9 -t greeting.ek9` in E81010/bad/ reports exactly E81010 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81010/bad/dev/tests.ek9","url":"https://ek9.io/errors/E81010.html","title":"E81010: invalid placeholder syntax in expected output","code":"#!ek9\ndefines module error.e81010.bad.tests\n\n  references\n    error.e81010.bad::greeting\n\n  defines program\n\n    @Test\n    GreetingOnce()\n      stdout <- Stdout()\n      stdout.println(greeting(\"EK9\"))","expectedOutput":null,"kind":"bad","errors":["E81010"],"validation":"`ek9 -t greeting.ek9` in E81010/bad/ reports exactly E81010 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81010/good/greeting.ek9","url":"https://ek9.io/errors/E81010.html","title":"The placeholder is the EK9 type String","code":"#!ek9\ndefines module error.e81010.good\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81010/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81010"}
{"id":"errors/E81010/good/dev/tests.ek9","url":"https://ek9.io/errors/E81010.html","title":"The placeholder is the EK9 type String","code":"#!ek9\ndefines module error.e81010.good.tests\n\n  references\n    error.e81010.good::greeting\n\n  defines program\n\n    @Test\n    GreetingOnce()\n      stdout <- Stdout()\n      stdout.println(greeting(\"EK9\"))","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81010/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81010"}
{"id":"errors/E81011/bad/dev/pricingTests.ek9","url":"https://ek9.io/errors/E81011.html","title":"E81011: assertion is not reachable from any @Test program","code":"#!ek9\ndefines module error.e81011.bad.tests\n\n  references\n    error.e81011.bad::discounted\n\n  defines function\n\n    checkNeverNegative()\n      -> price as Integer\n      assert discounted(price, 100) >= 0\n\n  defines program\n\n    @Test\n    TenPercentOff()\n      assert discounted(200, 10) == 180","expectedOutput":null,"kind":"bad","errors":["E81011"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81011/bad/pricing.ek9","url":"https://ek9.io/errors/E81011.html","title":"E81011: assertion is not reachable from any @Test program","code":"#!ek9\ndefines module error.e81011.bad\n\n  defines function\n\n    discounted() as pure\n      ->\n        price as Integer\n        percentOff as Integer\n      <- reduced as Integer: price - price * percentOff / 100","expectedOutput":null,"kind":"bad","errors":["E81011"],"validation":"a file of the error example E81011/bad/: compiled with the example's other files, it reports nothing itself, and the example fails with exactly the errors listed in errors (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81011/good/pricing.ek9","url":"https://ek9.io/errors/E81011.html","title":"A @Test program calls the helper, so its assertions run","code":"#!ek9\ndefines module error.e81011.good\n\n  defines function\n\n    discounted() as pure\n      ->\n        price as Integer\n        percentOff as Integer\n      <- reduced as Integer: price - price * percentOff / 100","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81011"}
{"id":"errors/E81011/good/dev/pricingTests.ek9","url":"https://ek9.io/errors/E81011.html","title":"A @Test program calls the helper, so its assertions run","code":"#!ek9\ndefines module error.e81011.good.tests\n\n  references\n    error.e81011.good::discounted\n\n  defines function\n\n    checkNeverNegative()\n      -> price as Integer\n      assert discounted(price, 100) >= 0\n\n  defines program\n\n    @Test\n    TenPercentOff()\n      assert discounted(200, 10) == 180\n\n    @Test\n    FullDiscountIsNeverNegative()\n      checkNeverNegative(200)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81011"}
{"id":"errors/E81012/bad/dev/pricingTests.ek9","url":"https://ek9.io/errors/E81012.html","title":"E81012: assertion is reachable from non-test program","code":"#!ek9\ndefines module error.e81012.bad.tests\n\n  references\n    error.e81012.bad::discounted\n\n  defines function\n\n    checkDiscount()\n      ->\n        percentOff as Integer\n        expected as Integer\n      assert discounted(200, percentOff) == expected\n\n  defines program\n\n    @Test\n    TenPercentOff()\n      checkDiscount(10, 180)\n\n    HalfPrice()\n      checkDiscount(50, 100)","expectedOutput":null,"kind":"bad","errors":["E81012"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81012/bad/pricing.ek9","url":"https://ek9.io/errors/E81012.html","title":"E81012: assertion is reachable from non-test program","code":"#!ek9\ndefines module error.e81012.bad\n\n  defines function\n\n    discounted() as pure\n      ->\n        price as Integer\n        percentOff as Integer\n      <- reduced as Integer: price - price * percentOff / 100","expectedOutput":null,"kind":"bad","errors":["E81012"],"validation":"a file of the error example E81012/bad/: compiled with the example's other files, it reports nothing itself, and the example fails with exactly the errors listed in errors (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81012/good/pricing.ek9","url":"https://ek9.io/errors/E81012.html","title":"Mark the program as the test it is","code":"#!ek9\ndefines module error.e81012.good\n\n  defines function\n\n    discounted() as pure\n      ->\n        price as Integer\n        percentOff as Integer\n      <- reduced as Integer: price - price * percentOff / 100","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81012"}
{"id":"errors/E81012/good/dev/pricingTests.ek9","url":"https://ek9.io/errors/E81012.html","title":"Mark the program as the test it is","code":"#!ek9\ndefines module error.e81012.good.tests\n\n  references\n    error.e81012.good::discounted\n\n  defines function\n\n    checkDiscount()\n      ->\n        percentOff as Integer\n        expected as Integer\n      assert discounted(200, percentOff) == expected\n\n  defines program\n\n    @Test\n    TenPercentOff()\n      checkDiscount(10, 180)\n\n    @Test\n    HalfPrice()\n      checkDiscount(50, 100)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81012"}
{"id":"errors/E81013/bad/greeting.ek9","url":"https://ek9.io/errors/E81013.html","title":"E81013: malformed line in envvars file (no '=' separator)","code":"#!ek9\ndefines module error.e81013.bad\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"bad","errors":["E81013"],"validation":"`ek9 -t greeting.ek9` in E81013/bad/ reports exactly E81013 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81013/bad/dev/tests.ek9","url":"https://ek9.io/errors/E81013.html","title":"E81013: malformed line in envvars file (no '=' separator)","code":"#!ek9\ndefines module error.e81013.bad.tests\n\n  references\n    error.e81013.bad::greeting\n\n  defines program\n\n    @Test\n    GreetingCases()\n      -> name as String\n      stdout <- Stdout()\n      stdout.println(greeting(name))","expectedOutput":null,"kind":"bad","errors":["E81013"],"validation":"`ek9 -t greeting.ek9` in E81013/bad/ reports exactly E81013 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81013/good/greeting.ek9","url":"https://ek9.io/errors/E81013.html","title":"Every line of the envvars file is NAME=VALUE","code":"#!ek9\ndefines module error.e81013.good\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81013/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81013"}
{"id":"errors/E81013/good/dev/tests.ek9","url":"https://ek9.io/errors/E81013.html","title":"Every line of the envvars file is NAME=VALUE","code":"#!ek9\ndefines module error.e81013.good.tests\n\n  references\n    error.e81013.good::greeting\n\n  defines program\n\n    @Test\n    GreetingCases()\n      -> name as String\n      stdout <- Stdout()\n      stdout.println(greeting(name))","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81013/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81013"}
{"id":"errors/E81014/bad/greeting.ek9","url":"https://ek9.io/errors/E81014.html","title":"E81014: orphan envvars file (no matching commandline args)","code":"#!ek9\ndefines module error.e81014.bad\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"bad","errors":["E81014"],"validation":"`ek9 -t greeting.ek9` in E81014/bad/ reports exactly E81014 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81014/bad/dev/tests.ek9","url":"https://ek9.io/errors/E81014.html","title":"E81014: orphan envvars file (no matching commandline args)","code":"#!ek9\ndefines module error.e81014.bad.tests\n\n  references\n    error.e81014.bad::greeting\n\n  defines program\n\n    @Test\n    GreetingCases()\n      -> name as String\n      stdout <- Stdout()\n      stdout.println(greeting(name))","expectedOutput":null,"kind":"bad","errors":["E81014"],"validation":"`ek9 -t greeting.ek9` in E81014/bad/ reports exactly E81014 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81014/good/greeting.ek9","url":"https://ek9.io/errors/E81014.html","title":"The envvars file belongs to a case: commandline_arg_other.txt","code":"#!ek9\ndefines module error.e81014.good\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81014/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81014"}
{"id":"errors/E81014/good/dev/tests.ek9","url":"https://ek9.io/errors/E81014.html","title":"The envvars file belongs to a case: commandline_arg_other.txt","code":"#!ek9\ndefines module error.e81014.good.tests\n\n  references\n    error.e81014.good::greeting\n\n  defines program\n\n    @Test\n    GreetingCases()\n      -> name as String\n      stdout <- Stdout()\n      stdout.println(greeting(name))","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81014/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81014"}
{"id":"errors/E81015/bad.ek9","url":"https://ek9.io/errors/E81015.html","title":"E81015: test construct only allowed in dev source files","code":"#!ek9\ndefines module error.e81015.bad\n\n  defines function\n\n    validateInput()\n      -> input as Integer\n      <- valid as Boolean?\n\n      assert input?\n\n      valid: true\n\n  defines program\n\n    MainProgram()\n      stdout <- Stdout()\n      stdout.println(\"Hello\")","expectedOutput":null,"kind":"bad","errors":["E81015"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81015/good.ek9","url":"https://ek9.io/errors/E81015.html","title":"Check an input in production code with 'require'; keep 'assert' for dev/ tests","code":"#!ek9\ndefines module error.e81015.good\n\n  defines function\n\n    validateInput()\n      -> input as Integer\n      <- valid as Boolean?\n      require input?\n      valid: true\n\n  defines program\n\n    MainProgram()\n      stdout <- Stdout()\n      stdout.println(\"Hello\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81015"}
{"id":"errors/E81016/bad/greeting.ek9","url":"https://ek9.io/errors/E81016.html","title":"E81016: orphan stdin file (no matching commandline args)","code":"#!ek9\ndefines module error.e81016.bad\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"bad","errors":["E81016"],"validation":"`ek9 -t greeting.ek9` in E81016/bad/ reports exactly E81016 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81016/bad/dev/tests.ek9","url":"https://ek9.io/errors/E81016.html","title":"E81016: orphan stdin file (no matching commandline args)","code":"#!ek9\ndefines module error.e81016.bad.tests\n\n  references\n    error.e81016.bad::greeting\n\n  defines program\n\n    @Test\n    GreetingCases()\n      -> name as String\n      stdout <- Stdout()\n      stdout.println(greeting(name))","expectedOutput":null,"kind":"bad","errors":["E81016"],"validation":"`ek9 -t greeting.ek9` in E81016/bad/ reports exactly E81016 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81016/good/greeting.ek9","url":"https://ek9.io/errors/E81016.html","title":"The stdin file belongs to a case: commandline_arg_other.txt","code":"#!ek9\ndefines module error.e81016.good\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81016/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81016"}
{"id":"errors/E81016/good/dev/tests.ek9","url":"https://ek9.io/errors/E81016.html","title":"The stdin file belongs to a case: commandline_arg_other.txt","code":"#!ek9\ndefines module error.e81016.good.tests\n\n  references\n    error.e81016.good::greeting\n\n  defines program\n\n    @Test\n    GreetingCases()\n      -> name as String\n      stdout <- Stdout()\n      stdout.println(greeting(name))","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E81016/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E81016"}
{"id":"errors/E81056/bad.ek9","url":"https://ek9.io/errors/E81056.html","title":"E81056: a closeable value held in a named local must be a try-with-resources resource","code":"#!ek9\ndefines module error.e81056.bad\n\n  defines function\n\n    firstLine()\n      -> path as FileSystemPath\n      <- rtn as String: String()\n      input <- TextFile(path).input()\n      if input.hasNext()\n        rtn: input.next()","expectedOutput":null,"kind":"bad","errors":["E81056"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81056/good.ek9","url":"https://ek9.io/errors/E81056.html","title":"Name it as a try-with-resources resource - the try closes it","code":"#!ek9\ndefines module error.e81056.good\n\n  defines function\n\n    firstLine()\n      -> path as FileSystemPath\n      <- rtn as String: String()\n      try\n        -> input <- TextFile(path).input()\n        if input.hasNext()\n          rtn: input.next()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81056"}
{"id":"errors/E81056/good_factory.ek9","url":"https://ek9.io/errors/E81056.html","title":"Or return it: ownership passes to the caller","code":"#!ek9\ndefines module error.e81056.good.factory\n\n  defines function\n\n    openData()\n      -> path as FileSystemPath\n      <- rtn as CloseableStringInput: TextFile(path).input()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81056"}
{"id":"errors/E81056/good_unnamed.ek9","url":"https://ek9.io/errors/E81056.html","title":"Or leave it unnamed - the statement that made it closes it","code":"#!ek9\ndefines module error.e81056.good.unnamed\n\n  defines function\n\n    allLines()\n      -> path as FileSystemPath\n      <- rtn as List of String: List()\n      cat TextFile(path).input() > rtn","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81056"}
{"id":"errors/E81057/bad.ek9","url":"https://ek9.io/errors/E81057.html","title":"E81057: a callable whose return type is closeable must return a NEW instance; to lend a held resource, return a non-closeable view type (e.g. StringInput)","code":"#!ek9\ndefines module error.e81057.bad\n\n  defines class\n\n    Res\n      name as String?\n\n      default private Res()\n\n      Res()\n        -> label as String\n        name: label\n\n      read() as pure\n        <- rtn as String: `read ${name}`\n\n      operator close as pure\n        stdout <- Stdout()\n        stdout.println(`closed ${name}`)\n\n      default operator ?\n\n    Holder\n      held as Res?\n\n      default private Holder()\n\n      Holder()\n        -> label as String\n        held: Res(label)\n\n      resource()\n        <- rtn as Res: held\n\n      default operator close\n\n      default operator ?\n\n  defines program\n\n    CloseableBorrowedReturn()\n      stdout <- Stdout()\n\n      try\n        -> holder <- Holder(\"heldInside\")\n        stdout.println(holder.resource().read())\n        stdout.println(\"still using holder\")\n        stdout.println(holder.resource().read())\n\n      stdout.println(\"done\")","expectedOutput":null,"kind":"bad","errors":["E81057"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81057/good.ek9","url":"https://ek9.io/errors/E81057.html","title":"Return a new instance - the caller owns it","code":"#!ek9\ndefines module error.e81057.good\n\n  defines class\n\n    Res\n      name as String?\n\n      default private Res()\n\n      Res()\n        -> label as String\n        name: label\n\n      read() as pure\n        <- rtn as String: `read ${name}`\n\n      operator close as pure\n        stdout <- Stdout()\n        stdout.println(`closed ${name}`)\n\n      default operator ?\n\n    Opener\n      label as String: \"fresh\"\n\n      open()\n        <- rtn as Res: Res(label)\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81057"}
{"id":"errors/E81057/good_loan.ek9","url":"https://ek9.io/errors/E81057.html","title":"Never hand a held resource out: lend it to a function for one call (the loan)","code":"#!ek9\ndefines module error.e81057.good.loan\n\n  defines function\n\n    LineUser() as abstract\n      -> lines as StringInput\n      <- rtn as Integer?\n\n    countLines() is LineUser\n      -> lines as StringInput\n      <- rtn as Integer: 0\n      while lines.hasNext()\n        line <- lines.next()\n        if not line.empty()\n          rtn++\n\n  defines class\n    Document\n      input as CloseableStringInput?\n\n      default private Document()\n\n      Document()\n        -> path as FileSystemPath\n        input: TextFile(path).input()\n\n      lend()\n        -> user as LineUser\n        <- rtn as Integer: user(input)\n\n      default operator close\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81057"}
{"id":"errors/E81059/bad.ek9","url":"https://ek9.io/errors/E81059.html","title":"E81059: a closeable value may only be stored where the declared type is closeable","code":"#!ek9\ndefines module error.e81059.bad\n\n  defines trait\n\n    Labelled\n      label() as pure\n        <- rtn as String?\n\n  defines class\n\n    LabelledResource with trait of Labelled\n      text as String?\n\n      default private LabelledResource()\n\n      LabelledResource()\n        -> initialText as String\n        text: initialText\n\n      override label() as pure\n        <- rtn as String: text\n\n      operator close as pure\n        require true\n\n      default operator ?\n\n    <?- BAD: a property declared as the non-closeable trait, initialised with a closeable -?>\n    TraitHolder\n      held as Labelled: LabelledResource(\"held\")\n\n      default operator ?\n\n    <?- BAD: a property re-pointed at a closeable, by name and through 'this' -?>\n    LateHolder\n      held as Labelled?\n\n      LateHolder()\n        held: LabelledResource(\"late\")\n\n      replaceHeld()\n        this.held := LabelledResource(\"replaced\")\n\n      default operator ?\n\n  defines function\n\n    <?- BAD: a local declared as the non-closeable trait -?>\n    storedAsTrait()\n      labelled as Labelled: LabelledResource(\"trait\")\n      require labelled?\n\n    <?- BAD: a local declared as Any -?>\n    storedAsAny()\n      anything as Any: LabelledResource(\"any\")\n      require anything?\n\n    <?- BAD: a built-in closeable input stored as the non-closeable StringInput -?>\n    storedAsStringInput()\n      input as StringInput: TextFile(\"lines.txt\").input()\n      require input?\n\n    <?- BAD: the returning variable declared as the non-closeable trait - the caller could never close it -?>\n    returnedAsTrait()\n      <- rtn as Labelled: LabelledResource(\"returned\")\n\n    <?- BAD: a declared, unset local later assigned a closeable -?>\n    assignedLater()\n      labelled as Labelled?\n      labelled := LabelledResource(\"later\")\n      require labelled?\n\n    <?- BAD: an assign-if-unset is a store too -?>\n    assignedIfUnset()\n      labelled as Labelled?\n      labelled :=? LabelledResource(\"guarded\")\n      require labelled?\n\n    <?- BAD: a try resource aliased into a non-closeable local outlives its try -?>\n    aliasOfTryResource()\n      outer as Labelled?\n      try\n        -> resource <- LabelledResource(\"aliased\")\n        outer := resource\n      require outer?","expectedOutput":null,"kind":"bad","errors":["E81059"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81059/good.ek9","url":"https://ek9.io/errors/E81059.html","title":"Keep the closeable type - in a try","code":"#!ek9\ndefines module error.e81059.good\n\n  defines function\n\n    firstLine()\n      -> path as FileSystemPath\n      <- rtn as String: String()\n      try\n        -> input <- TextFile(path).input()\n        if input.hasNext()\n          rtn: input.next()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81059"}
{"id":"errors/E81059/good_not_a_store.ek9","url":"https://ek9.io/errors/E81059.html","title":"What is not a store: a lent argument, a Closeable-typed try resource or return, an owning property","code":"#!ek9\ndefines module error.e81059.good.not.a.store\n\n  defines trait\n\n    Described\n      description() as pure\n        <- rtn as String?\n\n  defines class\n\n    DescribedResource with trait of Described, Closeable\n      text as String?\n\n      default private DescribedResource()\n\n      DescribedResource()\n        -> initialText as String\n        text: initialText\n\n      override description() as pure\n        <- rtn as String: text\n\n      override operator close as pure\n        require true\n\n      default operator ?\n\n    PlainDescription with trait of Described\n      text as String?\n\n      default private PlainDescription()\n\n      PlainDescription()\n        -> initialText as String\n        text: initialText\n\n      override description() as pure\n        <- rtn as String: text\n\n      default operator ?\n\n    <?- OK: a property declared as the closeable type is owned by its object, and closed by it -?>\n    ResourceOwner\n      owned as DescribedResource?\n\n      ResourceOwner()\n        owned: DescribedResource(\"owned\")\n\n      default operator close\n\n      default operator ?\n\n  defines function\n\n    describe() as pure\n      -> described as Described\n      <- rtn as String: described.description()\n\n    <?- OK: an unnamed closeable passed as an argument - lent, the statement still closes it -?>\n    unnamedArgument()\n      require describe(DescribedResource(\"argument\"))?\n\n    <?- OK: a try resource passed as an argument - lent, the try still closes it -?>\n    tryResourceArgument()\n      try\n        -> resource <- DescribedResource(\"try\")\n        require describe(resource)?\n\n    <?- OK: a try resource declared as the Closeable trait keeps its close -?>\n    tryResourceAsCloseable()\n      try\n        -> resource as Closeable: DescribedResource(\"closeable\")\n        require resource?\n\n    <?- OK: returning as the closeable type hands ownership to the caller -?>\n    returnedAsResource()\n      <- rtn as DescribedResource: DescribedResource(\"returned\")\n\n    <?- OK: returning as the Closeable trait keeps the close operator -?>\n    returnedAsCloseable()\n      <- rtn as Closeable: DescribedResource(\"closeable\")\n\n    <?- OK: a non-closeable value stored as the trait -?>\n    plainAsTrait()\n      described as Described: PlainDescription(\"plain\")\n      require described?\n\n    <?- OK: a standard stream is borrowed, not owned, so it may be held as StringInput -?>\n    standardInputAsStringInput()\n      input as StringInput: Stdin()\n      require input?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81059"}
{"id":"errors/E81060/bad.ek9","url":"https://ek9.io/errors/E81060.html","title":"E81060: the close operator is never called as a method, 'super.close()' included - make the value a try-with-resources resource; a type's own properties and its super class are closed by its generated close","code":"#!ek9\ndefines module error.e81060.bad\n\n  defines class\n\n    Res\n      name as String?\n\n      default private Res()\n\n      Res()\n        -> label as String\n        name: label\n\n      read() as pure\n        <- rtn as String: `read ${name}`\n\n      operator close as pure\n        stdout <- Stdout()\n        stdout.println(`closed ${name}`)\n\n      default operator ?\n\n  defines function\n\n    readOnce()\n      <- rtn as String?\n      try\n        -> res <- Res(\"journal\")\n        rtn: res.read()\n        res.close()","expectedOutput":null,"kind":"bad","errors":["E81060"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81060/good.ek9","url":"https://ek9.io/errors/E81060.html","title":"Let the owner close it - the try does, exactly once","code":"#!ek9\ndefines module error.e81060.good\n\n  defines class\n\n    Res\n      name as String?\n\n      default private Res()\n\n      Res()\n        -> label as String\n        name: label\n\n      read() as pure\n        <- rtn as String: `read ${name}`\n\n      operator close as pure\n        stdout <- Stdout()\n        stdout.println(`closed ${name}`)\n\n      default operator ?\n\n  defines function\n\n    readOnce()\n      <- rtn as String?\n      try\n        -> res <- Res(\"journal\")\n        rtn: res.read()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81060"}
{"id":"errors/E81060/good_subtype.ek9","url":"https://ek9.io/errors/E81060.html","title":"A sub type's close never calls 'super.close()': the generated chain calls it","code":"#!ek9\ndefines module error.e81060.good.subtype\n\n  defines class\n    Res as open\n      name as String?\n      default private Res()\n      Res()\n        -> label as String\n        name: label\n      operator close as pure\n        stdout <- Stdout()\n        stdout.println(`closed ${name}`)\n      default operator ?\n\n    LoggedRes extends Res\n      LoggedRes()\n        -> label as String\n        super(label)\n      //Its own work only: Res's close runs after it, generated\n      override operator close as pure\n        stdout <- Stdout()\n        stdout.println(\"closing\")\n\n  defines function\n    readOnce()\n      try\n        -> res <- LoggedRes(\"journal\")\n        require res?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81060"}
{"id":"errors/E81061/bad.ek9","url":"https://ek9.io/errors/E81061.html","title":"E81061: a closeable type is never a type argument - hold it as a property of a type you own (closed in its 'operator close'), acquire it in a try, or lend it as a parameter","code":"#!ek9\ndefines module error.e81061.bad\n\n  defines class\n\n    Res\n      name as String?\n\n      default private Res()\n\n      Res()\n        -> initialName as String\n        name: initialName\n\n      operator close as pure\n        require true\n\n      default operator ?\n\n    Box of type T\n      default Box() as pure\n\n      Box() as pure\n        -> seed as T\n        require seed?\n\n      default operator ?\n\n    <?- BAD: a property holding a list of closeables -?>\n    ListHolder\n      held as List of Res?\n\n      default operator ?\n\n    <?- A type closeable only through its super, declared before that super -?>\n    SubRes extends BaseRes\n      default SubRes()\n\n      default operator ?\n\n    BaseRes as open\n      default BaseRes()\n\n      operator close as pure\n        require true\n\n      default operator ?\n\n    <?- VALID: a closeable held as a property of a type you own, closed in its operator close -?>\n    Owner\n      held as Res?\n\n      default private Owner()\n\n      Owner()\n        -> name as String\n        held: Res(name)\n\n      default operator close\n\n      default operator ?\n\n  defines function\n\n    <?- BAD: a parameter typed as a list of closeables -?>\n    listParameter()\n      -> resources as List of Res\n      require resources?\n\n    <?- BAD: a nested type argument -?>\n    nestedListParameter()\n      -> resources as List of List of Res\n      require resources?\n\n    <?- BAD: an Optional of a built-in closeable as the returning variable -?>\n    optionalReturn() as abstract\n      <- rtn as Optional of TCP?\n\n    <?- BAD: a closeable as a Dict value type -?>\n    dictParameter()\n      -> servers as Dict of (String, HTTP)\n      require servers?\n\n    <?- BAD: a user generic parameterised with a closeable -?>\n    boxConstruction()\n      boxes <- Box() of Res\n      require boxes?\n\n    <?- BAD: a generic function type parameterised with a closeable -?>\n    acceptorParameter()\n      -> handler as Acceptor of TCP\n      require handler?\n\n    <?- BAD: an empty list of a built-in closeable input -?>\n    listConstruction()\n      inputs <- List() of CloseableStringInput\n      require inputs?\n\n    <?- BAD: the Closeable trait itself, and a type closeable only through its super -?>\n    closeableTraitParameter()\n      -> resources as List of Closeable\n      require resources?\n\n    inheritedCloseParameter()\n      -> resources as Optional of SubRes\n      require resources?\n\n    <?- VALID: the standard streams have a close operator but are never closed, so they are not closeable here -?>\n    standardOutputs()\n      -> outputs as List of Stdout\n      require outputs?\n\n    <?- VALID: a closeable lent as a parameter -?>\n    lentParameter()\n      -> res as Res\n      require res?\n\n    <?- VALID: a generic of a non-closeable type -?>\n    nonCloseableList()\n      -> names as List of String\n      require names?","expectedOutput":null,"kind":"bad","errors":["E81061"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81061/good.ek9","url":"https://ek9.io/errors/E81061.html","title":"Hold the closeable in a property of a type you own, or acquire it in a try and lend it","code":"#!ek9\ndefines module error.e81061.good\n\n  defines class\n\n    Res\n      name as String?\n\n      default private Res()\n\n      Res()\n        -> label as String\n        name: label\n\n      read() as pure\n        <- rtn as String: `read ${name}`\n\n      operator close as pure\n        stdout <- Stdout()\n        stdout.println(`closed ${name}`)\n\n      default operator ?\n\n    Pair\n      first as Res?\n      second as Res?\n\n      default private Pair()\n\n      Pair()\n        -> label as String\n        first: Res(`${label} one`)\n        second: Res(`${label} two`)\n\n      default operator close\n      default operator ?\n\n  defines function\n\n    use()\n      -> res as Res\n      <- rtn as String: res.read()\n\n    lend()\n      <- rtn as String?\n      try\n        -> res <- Res(\"lent\")\n        rtn: use(res)","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81061"}
{"id":"errors/E81062/bad.ek9","url":"https://ek9.io/errors/E81062.html","title":"E81062: a closeable value enters a property or a try resource only when it is NEW (a constructor call, or a call that returns a new closeable) - anything else already has an owner that closes it","code":"#!ek9\ndefines module error.e81062.bad\n\n  defines class\n\n    Res\n      name as String?\n\n      default private Res()\n\n      Res()\n        -> label as String\n        name: label\n\n      read() as pure\n        <- rtn as String: `read ${name}`\n\n      operator close as pure\n        stdout <- Stdout()\n        stdout.println(`closed ${name}`)\n\n      default operator ?\n\n    Holder\n      held as Res?\n\n      default private Holder()\n\n      Holder()\n        -> res as Res\n        held: res\n\n      default operator close\n      default operator ?\n\n  defines function\n\n    share()\n      <- rtn as Boolean?\n      try\n        ->\n          res <- Res(\"shared\")\n          holder <- Holder(res)\n        rtn: holder?","expectedOutput":null,"kind":"bad","errors":["E81062"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81062/good.ek9","url":"https://ek9.io/errors/E81062.html","title":"Hand the slot a new value - the holder is its only owner","code":"#!ek9\ndefines module error.e81062.good\n\n  defines class\n\n    Res\n      name as String?\n\n      default private Res()\n\n      Res()\n        -> label as String\n        name: label\n\n      read() as pure\n        <- rtn as String: `read ${name}`\n\n      operator close as pure\n        stdout <- Stdout()\n        stdout.println(`closed ${name}`)\n\n      default operator ?\n\n    Holder\n      held as Res?\n\n      default private Holder()\n\n      Holder()\n        -> res as Res\n        held: res\n\n      default operator close\n      default operator ?\n\n  defines function\n\n    share()\n      <- rtn as Boolean?\n      try\n        -> holder <- Holder(Res(\"shared\"))\n        rtn: holder?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81062"}
{"id":"errors/E81063/bad.ek9","url":"https://ek9.io/errors/E81063.html","title":"E81063: a closeable slot is assigned once - a property in its own constructor or initialiser, a returning variable once on each path (declared unset), a try resource only by its try; re-pointing it drops the resource it held","code":"#!ek9\ndefines module error.e81063.bad\n\n  defines class\n\n    Res\n      name as String?\n\n      default private Res()\n\n      Res()\n        -> label as String\n        name: label\n\n      read() as pure\n        <- rtn as String: `read ${name}`\n\n      operator close as pure\n        stdout <- Stdout()\n        stdout.println(`closed ${name}`)\n\n      default operator ?\n\n    Client\n      conn as Res?\n\n      Client()\n        conn: Res(\"first\")\n\n      reconnect()\n        conn := Res(\"second\")\n\n      default operator close\n      default operator ?\n\n  defines function\n\n    choose()\n      -> choice as Boolean\n      <- rtn as Res: Res(\"default\")\n      if choice\n        rtn: Res(\"chosen\")","expectedOutput":null,"kind":"bad","errors":["E81063"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81063/good.ek9","url":"https://ek9.io/errors/E81063.html","title":"Use a fresh resource per try; give a returning variable one value on each path","code":"#!ek9\ndefines module error.e81063.good\n\n  defines class\n\n    Res\n      name as String?\n\n      default private Res()\n\n      Res()\n        -> label as String\n        name: label\n\n      read() as pure\n        <- rtn as String: `read ${name}`\n\n      operator close as pure\n        stdout <- Stdout()\n        stdout.println(`closed ${name}`)\n\n      default operator ?\n\n  defines function\n\n    callTwice()\n      <- rtn as String: String()\n      for attempt in 1 ... 2\n        try\n          -> conn <- Res(`attempt ${attempt}`)\n          rtn: conn.read()\n\n    choose()\n      -> choice as Boolean\n      <- rtn as Res?\n      if choice\n        rtn: Res(\"chosen\")\n      else\n        rtn: Res(\"default\")","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81063"}
{"id":"errors/E81064/bad.ek9","url":"https://ek9.io/errors/E81064.html","title":"E81064: closeable properties are closed in reverse declaration order, so a constructor must acquire them in declaration order","code":"#!ek9\ndefines module error.e81064.bad\n\n  defines class\n\n    Res\n      name as String?\n\n      default private Res()\n\n      Res()\n        -> label as String\n        name: label\n\n      operator close as pure\n        require name?\n\n      default operator ?\n\n    <?- BAD: 'dependent' is declared first but acquired second -?>\n    BodyOrder\n      dependent as Res?\n      foundation as Res?\n\n      BodyOrder()\n        foundation: Res(\"foundation\")\n        dependent: Res(\"dependent\")\n\n      default operator close\n\n      default operator ?\n\n    <?- BAD: 'late' is initialised before the constructor body sets 'early', which is declared before it -?>\n    InitialiserFirst\n      early as Res?\n      late as Res: Res(\"late\")\n\n      InitialiserFirst()\n        early: Res(\"early\")\n\n      default operator close\n\n      default operator ?\n\n    <?- BAD: out of order on one path is enough -?>\n    OnOnePath\n      first as Res?\n      second as Res?\n\n      default private OnOnePath()\n\n      OnOnePath()\n        -> secondFirst as Boolean\n        if secondFirst\n          second: Res(\"second\")\n          first: Res(\"first\")\n        else\n          first: Res(\"first\")\n          second: Res(\"second\")\n\n      default operator close\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E81064"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81064/good.ek9","url":"https://ek9.io/errors/E81064.html","title":"Declare the closeable properties in the order they are acquired","code":"#!ek9\ndefines module error.e81064.good\n\n  defines class\n\n    Res\n      name as String?\n\n      default private Res()\n\n      Res()\n        -> label as String\n        name: label\n\n      read() as pure\n        <- rtn as String: `read ${name}`\n\n      operator close as pure\n        stdout <- Stdout()\n        stdout.println(`closed ${name}`)\n\n      default operator ?\n\n    BodyOrder\n      foundation as Res?\n      dependent as Res?\n\n      BodyOrder()\n        foundation: Res(\"foundation\")\n        dependent: Res(\"dependent\")\n\n      default operator close\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81064"}
{"id":"errors/E81065/bad.ek9","url":"https://ek9.io/errors/E81065.html","title":"E81065: 'default operator :=:' cannot copy a closeable property - the copy would share the resource and both objects would close it","code":"#!ek9\ndefines module error.e81065.bad\n\n  defines class\n\n    Res\n      name as String?\n\n      default private Res()\n\n      Res()\n        -> label as String\n        name: label\n\n      operator close as pure\n        require name?\n\n      default operator\n\n    <?- BAD: the copy operator asked for explicitly -?>\n    ExplicitCopy\n      held as Res?\n\n      default private ExplicitCopy()\n\n      ExplicitCopy()\n        -> label as String\n        held: Res(label)\n\n      default operator close\n\n      default operator :=:\n\n      default operator ?\n\n    <?- BAD: the bare 'default operator' includes the copy operator -?>\n    BareDefaults\n      label as String?\n      held as Res?\n\n      default private BareDefaults()\n\n      BareDefaults()\n        -> text as String\n        label: text\n        held: Res(text)\n\n      default operator close\n\n      default operator\n\n    <?- OK: a hand-written copy that copies only what is not a resource -?>\n    HandWrittenCopy\n      label as String?\n      held as Res?\n\n      default private HandWrittenCopy()\n\n      HandWrittenCopy()\n        -> text as String\n        label: text\n        held: Res(text)\n\n      operator :=:\n        -> other as HandWrittenCopy\n        label :=: other.label\n\n      default operator close\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E81065"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81065/good.ek9","url":"https://ek9.io/errors/E81065.html","title":"Ask only for the operators the type needs, or write a copy that leaves the resource alone","code":"#!ek9\ndefines module error.e81065.good\n\n  defines class\n\n    Res\n      name as String?\n\n      default private Res()\n\n      Res()\n        -> label as String\n        name: label\n\n      read() as pure\n        <- rtn as String: `read ${name}`\n\n      operator close as pure\n        stdout <- Stdout()\n        stdout.println(`closed ${name}`)\n\n      default operator ?\n\n    HandWrittenCopy\n      label as String?\n      held as Res?\n\n      default private HandWrittenCopy()\n\n      HandWrittenCopy()\n        -> text as String\n        label: text\n        held: Res(text)\n\n      operator :=:\n        -> other as HandWrittenCopy\n        label :=: other.label\n\n      default operator close\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81065"}
{"id":"errors/E81066/bad.ek9","url":"https://ek9.io/errors/E81066.html","title":"E81066: a trait's 'operator close' is abstract (no body) - a trait holds no properties, so it has nothing to close; the class that holds the resource closes it in its own 'operator close'","code":"#!ek9\ndefines module error.e81066.bad\n\n  defines trait\n\n    <?- VALID: a trait's operator close with no body is abstract -?>\n    Releasable\n      operator close as pure\n\n    <?- VALID: the same, with 'abstract' written out -?>\n    ExplicitlyReleasable\n      operator close as pure abstract\n\n    <?- BAD: a trait's operator close with a body -?>\n    LoggingReleasable\n      operator close as pure\n        stdout <- Stdout()\n        stdout.println(\"closing\")\n\n    <?- BAD: even a body that only checks something -?>\n    CheckingReleasable\n      operator close as pure\n        require true\n\n    <?- BAD: a trait extending a closeable trait and adding a close body -?>\n    ExtendedReleasable with trait of Releasable\n      override operator close as pure\n        require true\n\n  defines class\n\n    <?- VALID: the class with the trait implements the close itself -?>\n    Resource with trait of Releasable\n      name as String?\n\n      default private Resource()\n\n      Resource()\n        -> resourceName as String\n        name: resourceName\n\n      override operator close as pure\n        require name?\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E81066"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81066/good.ek9","url":"https://ek9.io/errors/E81066.html","title":"Leave the trait's close abstract; the class that holds the resource closes it","code":"#!ek9\ndefines module error.e81066.good\n\n  defines trait\n\n    Releasable\n      operator close as pure\n\n  defines class\n\n    Resource with trait of Releasable\n      name as String?\n\n      default private Resource()\n\n      Resource()\n        -> resourceName as String\n        name: resourceName\n\n      override operator close as pure\n        stdout <- Stdout()\n        stdout.println(`closing ${name}`)\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81066"}
{"id":"errors/E81067/bad.ek9","url":"https://ek9.io/errors/E81067.html","title":"E81067: if you hold it, you close it - a type with a closeable property must declare its own 'operator close' ('default operator close' or one you write); an inherited close cannot see this type's property","code":"#!ek9\ndefines module error.e81067.bad\n\n  defines class\n\n    Res\n      name as String?\n\n      default private Res()\n\n      Res()\n        -> label as String\n        name: label\n\n      read() as pure\n        <- rtn as String: `read ${name}`\n\n      operator close as pure\n        stdout <- Stdout()\n        stdout.println(`closed ${name}`)\n\n      default operator ?\n\n    Ledger as open\n      book as Res?\n\n      default private Ledger()\n\n      Ledger()\n        -> title as String\n        book: Res(title)\n\n      default operator close\n      default operator ?\n\n    Journal is Ledger\n      notes as Res?\n\n      Journal()\n        -> title as String\n        super(title)\n        notes: Res(`${title} notes`)\n\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E81067"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81067/good.ek9","url":"https://ek9.io/errors/E81067.html","title":"Declare its own close - the generated close closes notes, then calls Ledger's","code":"#!ek9\ndefines module error.e81067.good\n\n  defines class\n\n    Res\n      name as String?\n\n      default private Res()\n\n      Res()\n        -> label as String\n        name: label\n\n      read() as pure\n        <- rtn as String: `read ${name}`\n\n      operator close as pure\n        stdout <- Stdout()\n        stdout.println(`closed ${name}`)\n\n      default operator ?\n\n    Ledger as open\n      book as Res?\n\n      default private Ledger()\n\n      Ledger()\n        -> title as String\n        book: Res(title)\n\n      default operator close\n      default operator ?\n\n    Journal is Ledger\n      notes as Res?\n\n      Journal()\n        -> title as String\n        super(title)\n        notes: Res(`${title} notes`)\n\n      default operator close\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81067"}
{"id":"errors/E81068/bad.ek9","url":"https://ek9.io/errors/E81068.html","title":"E81068: the 'operator close' of an open or abstract type can never call a method a subtype may override, nor hand out 'this' - a subtype's own properties are closed before this body runs","code":"#!ek9\ndefines module error.e81068.bad\n\n  defines class\n\n    Out\n      name as String?\n\n      default private Out()\n\n      Out()\n        -> label as String\n        name: label\n\n      write() as pure\n        -> text as String\n        require text?\n\n      operator close as pure\n        require name?\n\n      default operator ?\n\n    <?- BAD: an open type's close calls a method a subtype may override -?>\n    FlushingBase as open\n      label as String?\n\n      FlushingBase()\n        label: \"base\"\n\n      flush() as pure\n        require label?\n\n      operator close as pure\n        flush()\n\n      default operator ?\n\n    <?- BAD: the same call written through 'this' -?>\n    ThisFlushingBase as open\n      label as String?\n\n      ThisFlushingBase()\n        label: \"base\"\n\n      flush() as pure\n        require label?\n\n      operator close as pure\n        this.flush()\n\n      default operator ?\n\n    <?- BAD: an abstract type's close calls its own abstract method -?>\n    AbstractBase as abstract\n      label as String?\n\n      AbstractBase()\n        label: \"abstract\"\n\n      describe() as pure abstract\n        <- rtn as String?\n\n      operator close as pure\n        text <- describe()\n        require text?\n\n      default operator ?\n\n    <?- BAD: an open type's close hands out 'this' -?>\n    ReportingBase as open\n      label as String?\n\n      ReportingBase()\n        label: \"reporting\"\n\n      operator close as pure\n        report(this)\n\n      default operator ?\n\n    <?- BAD: a call to the super's method from an open type's close - the super's method can call back into an override -?>\n    ChainedBase is FlushingBase as open\n      out as Out?\n\n      ChainedBase()\n        super()\n        out: Out(\"chained\")\n\n      override operator close as pure\n        super.flush()\n\n      default operator ?\n\n    <?- VALID: a private helper cannot be overridden -?>\n    PrivateHelperBase as open\n      label as String?\n\n      PrivateHelperBase()\n        label: \"private\"\n\n      private tidy() as pure\n        require label?\n\n      operator close as pure\n        tidy()\n\n      default operator ?\n\n    <?- VALID: calling methods of a property the type holds, and closing it -?>\n    HolderBase as open\n      out as Out?\n\n      HolderBase()\n        out: Out(\"held\")\n\n      operator close as pure\n        out.write(\"final\")\n\n      default operator ?\n\n    <?- VALID: an overriding close chaining to the super's close -?>\n    HolderSub is HolderBase as open\n      extra as Out?\n\n      HolderSub()\n        super()\n        extra: Out(\"extra\")\n\n      default operator close\n\n      default operator ?\n\n    <?- VALID: a closed type has no subtype, so its close may call its own methods and use 'this' -?>\n    ClosedType\n      label as String?\n\n      ClosedType()\n        label: \"closed\"\n\n      flush() as pure\n        require label?\n\n      operator close as pure\n        flush()\n        report(this)\n\n      default operator ?\n\n  defines function\n\n    report() as pure\n      -> item as Any\n      require item?","expectedOutput":null,"kind":"bad","errors":["E81068"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81068/good.ek9","url":"https://ek9.io/errors/E81068.html","title":"In an open type, close only calls private helpers and what its properties hold","code":"#!ek9\ndefines module error.e81068.good\n\n  defines class\n\n    Out\n      name as String?\n\n      default private Out()\n\n      Out()\n        -> label as String\n        name: label\n\n      write() as pure\n        -> text as String\n        require text?\n\n      operator close as pure\n        require name?\n\n      default operator ?\n\n    PrivateHelperBase as open\n      label as String?\n\n      PrivateHelperBase()\n        label: \"private\"\n\n      private tidy() as pure\n        require label?\n\n      operator close as pure\n        tidy()\n\n      default operator ?\n\n    HolderBase as open\n      out as Out?\n\n      HolderBase()\n        out: Out(\"held\")\n\n      operator close as pure\n        out.write(\"final\")\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81068"}
{"id":"errors/E81069/bad.ek9","url":"https://ek9.io/errors/E81069.html","title":"E81069: a dynamic function has no 'operator close', so it can never close a NEW closeable it captures - capture one the enclosing scope owns (a try resource), or capture it in a dynamic class that closes it","code":"#!ek9\ndefines module error.e81069.bad\n\n  defines class\n\n    Res\n      name as String?\n\n      default private Res()\n\n      Res()\n        -> label as String\n        name: label\n\n      read() as pure\n        <- rtn as String: `read ${name}`\n\n      operator close as pure\n        stdout <- Stdout()\n        stdout.println(`closed ${name}`)\n\n      default operator ?\n\n  defines function\n\n    Reader() as abstract\n      <- text as String?\n\n    makeReader()\n      <- rtn as Boolean?\n      reader <- (res: Res(\"journal\")) is Reader as function\n        text: res.read()\n      rtn: reader?","expectedOutput":null,"kind":"bad","errors":["E81069"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81069/good.ek9","url":"https://ek9.io/errors/E81069.html","title":"Acquire it in a try and capture it by name - a borrow; the try closes it","code":"#!ek9\ndefines module error.e81069.good\n\n  defines class\n\n    Res\n      name as String?\n\n      default private Res()\n\n      Res()\n        -> label as String\n        name: label\n\n      read() as pure\n        <- rtn as String: `read ${name}`\n\n      operator close as pure\n        stdout <- Stdout()\n        stdout.println(`closed ${name}`)\n\n      default operator ?\n\n  defines function\n\n    Reader() as abstract\n      <- text as String?\n\n    readJournal()\n      <- rtn as String?\n      try\n        -> res <- Res(\"journal\")\n        reader <- (res) is Reader as function\n          text: res.read()\n        rtn: reader()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81069"}
{"id":"errors/E81069/good_class.ek9","url":"https://ek9.io/errors/E81069.html","title":"Or capture the new value in a dynamic CLASS, whose generated close closes it","code":"#!ek9\ndefines module error.e81069.good.class\n\n  defines class\n    Res\n      name as String?\n      default private Res()\n      Res()\n        -> label as String\n        name: label\n      read() as pure\n        <- rtn as String: `read ${name}`\n      operator close as pure\n        stdout <- Stdout()\n        stdout.println(`closed ${name}`)\n      default operator ?\n\n  defines trait\n    Readable\n      text() as abstract\n        <- rtn as String?\n\n  defines function\n    readJournal()\n      <- rtn as String?\n      try\n        -> reader <- (res: Res(\"journal\")) with trait of Readable as class\n          override text()\n            <- rtn as String: res.read()\n          default operator close\n          default operator ?\n        rtn: reader.text()","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81069"}
{"id":"errors/E81070/bad.ek9","url":"https://ek9.io/errors/E81070.html","title":"E81070: 'default operator close' with nothing to close - no closeable property and no super class close - would only make the type closeable, forcing every caller into a 'try'; remove it","code":"#!ek9\ndefines module error.e81070.bad\n\n  defines class\n\n    Settings\n      path as String: \"settings.txt\"\n\n      default operator close\n      default operator ?","expectedOutput":null,"kind":"bad","errors":["E81070"],"validation":"fails with exactly the errors listed in errors - those errors, at their phase, nothing else (ErrorExamplesTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E81070/good.ek9","url":"https://ek9.io/errors/E81070.html","title":"Remove it - a type with nothing to close is not closeable","code":"#!ek9\ndefines module error.e81070.good\n\n  defines class\n\n    Settings\n      path as String: \"settings.txt\"\n\n      default operator ?","expectedOutput":null,"kind":"good","errors":[],"validation":"compiled with no errors through full code generation, with the code's other fixes (ErrorExamplesTest, the -Psite gate step); not run","origin":"error-good","fixes":"E81070"}
{"id":"errors/E83001/bad/greeting.ek9","url":"https://ek9.io/errors/E83001.html","title":"E83001: code coverage below threshold","code":"#!ek9\ndefines module error.e83001.bad\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`\n\n    shout() as pure\n      -> name as String\n      <- result as String: greeting(name).upperCase()\n\n    whisper() as pure\n      -> name as String\n      <- result as String: greeting(name).lowerCase()\n\n    padded() as pure\n      -> name as String\n      <- result as String: ` ${greeting(name)} `","expectedOutput":null,"kind":"bad","errors":["E83001"],"validation":"`ek9 -t greeting.ek9` in E83001/bad/ reports exactly E83001 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E83001/bad/dev/tests.ek9","url":"https://ek9.io/errors/E83001.html","title":"E83001: code coverage below threshold","code":"#!ek9\ndefines module error.e83001.bad.tests\n\n  references\n    error.e83001.bad::greeting\n\n  defines program\n\n    @Test\n    GreetingIsKept()\n      assert greeting(\"EK9\") == \"Hello, EK9\"","expectedOutput":null,"kind":"bad","errors":["E83001"],"validation":"`ek9 -t greeting.ek9` in E83001/bad/ reports exactly E83001 (the test runner, not the compiler) and no other E8xxxx (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-bad"}
{"id":"errors/E83001/good/greeting.ek9","url":"https://ek9.io/errors/E83001.html","title":"Every function has a test","code":"#!ek9\ndefines module error.e83001.good\n\n  defines function\n\n    greeting() as pure\n      -> name as String\n      <- result as String: `Hello, ${name}`\n\n    shout() as pure\n      -> name as String\n      <- result as String: greeting(name).upperCase()\n\n    whisper() as pure\n      -> name as String\n      <- result as String: greeting(name).lowerCase()\n\n    padded() as pure\n      -> name as String\n      <- result as String: ` ${greeting(name)} `","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E83001/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E83001"}
{"id":"errors/E83001/good/dev/tests.ek9","url":"https://ek9.io/errors/E83001.html","title":"Every function has a test","code":"#!ek9\ndefines module error.e83001.good.tests\n\n  references\n    error.e83001.good::greeting\n    error.e83001.good::padded\n    error.e83001.good::shout\n    error.e83001.good::whisper\n\n  defines program\n\n    @Test\n    GreetingIsKept()\n      assert greeting(\"EK9\") == \"Hello, EK9\"\n\n    @Test\n    ShoutIsUpperCase()\n      assert shout(\"EK9\") == \"HELLO, EK9\"\n\n    @Test\n    WhisperIsLowerCase()\n      assert whisper(\"EK9\") == \"hello, ek9\"\n\n    @Test\n    PaddedHasSpaces()\n      assert padded(\"EK9\") == \" Hello, EK9 \"","expectedOutput":null,"kind":"good","errors":[],"validation":"`ek9 -t greeting.ek9` in E83001/good/ passes (ErrorExampleRunnerOutputTest, the -Psite gate step)","origin":"error-good","fixes":"E83001"}
