Search the IDE pages
Every section of the IDE pages, with its text. Type to narrow the list; every word must match.
| Page | Section | Text |
|---|---|---|
| The EK9 IDE | The EK9 IDE | The EK9 IDE is a desktop editor for EK9 with the compiler built in. You start it with ek9 -ide. ek9 -ide The EK9 IDE with helloworld.ek9 open: two hovers on the right describe stdout and println, and the run dialog shows Success with the output Hello, World! |
| The EK9 IDE | What you need | ek9 -ide starts the IDE. Like the rest of EK9, it needs Java 25 or later. |
| The EK9 IDE | A first program | Your first project makes a new project and runs a program in it, step by step, with a picture of each step. To open a directory of .ek9 files you already have, use File > Open Project…, open a source file, and run its program with Run > Run Program…. Here is the program from the introduction: The ... |
| The EK9 IDE | The lessons | The IDE teaches itself in lessons: each one shows you an action step by step, then watches while you do it. Each lesson has a page of its own here, with every step and a picture of the IDE once it is done. To play one in the IDE, choose Help > Lessons and its group, or run ek9 -ide -lesson <name>. |
| The EK9 IDE | Getting started | Your first project, and finding your way round the IDE. Your first project: A new project, a new file, the example program pasted in from the answers, and run. |
| The EK9 IDE | Finding | Search and replace, in Text or Symbols mode, across one file, a module or the whole project - and the two other ways of finding your way, Find Construct and Find References. Find: text: Type into the find bar and watch the count update live, step through matches with Find Next/Previous, then ... |
| The EK9 IDE | Writing code | New constructs - classes, functions, records - and the fields, methods and operators they hold; the examples of Getting Started with EK9. Chapter 16: a class, built: Build the book's Counter class and its program with the IDE's own tools - New Construct, Add Field, Add Method - typing only the ... |
| The EK9 IDE | Refactoring | Rename, extract, inline, change a signature, move: each previewed before it is applied. Extract Constant: Give a literal a name: a constant defined once, and every use of the literal in the file replaced by it.Rename Symbol: Rename a name and every use of it, wherever it is - for a name that says ... |
| The EK9 IDE | Debugging and the Journal | Breakpoints and stepping, and the Journal: a run recorded and read backwards to its cause. The Journal: one run: Record every change to one value while a program runs, then read the failure backwards to its cause.The Journal: comparing runs: Record several runs, choose a passing one and the ... |
| The EK9 IDE | Understanding a codebase | The Analyse views: what calls what, what depends on what. Show Blast Radius: See who a purity change would reach before you make it - the callers that break if pure is removed, the callees that must become pure if it is added - from the right-click Show Blast Radius item, at the point of pain. |
| The EK9 IDE | Security, packages and Git | Sanitised input, packages and their versions, and Git. Capabilities: The security-capability audit window: every gated system type the code uses against what the package declares - under-declared (the E12010 set) fixed with Add Capability, over-declared (declared but unused) tidied with Remove ... |
| The EK9 IDE | Fixing errors | Every error EK9 reports is explained - in the Help tab, or by ek9 -h and its code - and the explanation ends with "Show me how to fix it": a lesson that opens the error's example and fixes it, step by step. They are listed in the error index. |
| The EK9 IDE | The menus | Each menu holds one kind of action. Right-click in the editor for everything that applies where the caret is, or use Refactor > Refactor This… (Ctrl+T) for the same menu from the keyboard. MenuWhat it holdsFileNew Project…, Open Project…, Recent Projects, Save, Save All, Settings…EditUndo, ... |
| The EK9 IDE | Using VS Code or IntelliJ instead | The EK9 extension for VS Code (vscode-ek9-ls) starts the EK9 language server, ek9 -ls. The server reports the compiler's errors as you type, and answers hover, completion, go to definition and find references. The EK9 plugin for IntelliJ (intellij-ek9-ls) uses the same language server, and the ... |
| The EK9 IDE | The language | This section covers the IDE. The language itself is in the EK9 language reference, starting with Structure. |
| Your first project | Your first project | This page makes a first project in the EK9 IDE and runs a program in it. It follows Help > Getting Started, and every picture is of the IDE doing each step. |
| Your first project | The IDE as it first opens | Start the IDE with ek9 -ide. With no project open it shows the Welcome page, with the keys for the most used actions and, under the title, New to EK9? Getting Started, which shows these same steps in the IDE's Help tab. The EK9 IDE with no project open: the Welcome page lists keyboard shortcuts ... |
| Your first project | Step 1: A new project | A project is a folder that holds your .ek9 files. Choose File > New Project…. The File menu open, with New Project… highlighted above Open Project…, Recent Projects, Save, Save All, Settings… and Exit Choose where the folder goes and give it a name. The name is hello to start with; the line at ... |
| Your first project | Step 2: A new EK9 file | In the Project panel, right-click the project and choose New EK9 File…. The Project panel with the project hello right-clicked: a menu with New Directory…, New EK9 File… (highlighted) and Add dev Name it HelloWorld.ek9. The module name is filled in from the project, and the file opens with its ... |
| Your first project | Step 3: The example program | Help > Getting Started shows the steps in the Help tab. Click ek9 -q 1 in step 3. The Help tab showing GETTING STARTED: the steps in the IDE and in a terminal, with the command ek9 -q 1 in step 3 underlined as a link The Answers tab opens at the answer to What does a minimal EK9 program look ... |
| Your first project | Step 4: Paste it in | In HelloWorld.ek9, select everything (Cmd+A on a Mac, Ctrl+A elsewhere) and paste (Cmd+V or Ctrl+V) the example over it, then save (Cmd+S or Ctrl+S). Saving compiles it: the status bar says Build clean, and a green run arrow appears beside the program's name, MinimalProgram(). HelloWorld.ek9 ... |
| Your first project | Step 5: Run it | Click the run arrow. Run Program opens with the program chosen; a program that takes arguments has them typed here. Choose Run. The Run Program dialog with MinimalProgram chosen, from HelloWorld.ek9 line 5, no run configurations, an empty Arguments field, and Cancel and Run The program runs and ... |
| Your first project | Next | The program's parts, and what to read next: ek9 -h quickstart in a terminal, or the Structure of an EK9 program in the language reference.Ask about anything in your own words: type it in the bar at the top of the IDE, or ek9 -q and your question in a terminal. |
| Find: text | Find: text | The find bar (Edit › Find…) searches this file's text as you type, with a live count of every match. total appears here as a class, a field, a method's tail (subtotal), a local, and inside a comment and a String. To play it in the IDE: Help > Lessons > Finding…, or ek9 -ide -lesson find-text. The ... |
| Find: text | Step 1: Type to search | Choose Edit > Find… The EK9 IDE once this is done: Choose Edit > Find… Type total into the field. The count updates as you type - 15 matches, comments and Strings included. The EK9 IDE once this is done: Type total into the field |
| Find: text | Step 2: Step through the matches | Choose the ↓ (or press Enter) to go to the next match. The EK9 IDE once this is done: Choose the ↓ (or press Enter) to go to the next match Choose the ↑ (or press Shift+Enter) to go back to the previous match. The EK9 IDE once this is done: Choose the ↑ (or press Shift+Enter) to go back to the ... |
| Find: text | Step 3: Whole word | Turn on Whole word (W). total is one word, so it no longer matches inside subtotal - the count drops to 12. The EK9 IDE once this is done: Turn on Whole word (W) |
| Find: text | Step 4: Match case | Turn off Whole word, then turn on Match case (Aa). Capital-letter Total - the class itself, and the others spelled with a capital T - no longer match: 11 matches. The EK9 IDE once this is done: Turn off Whole word, then turn on Match case (Aa) Choose the ✕ (or press Escape) to close the find bar. ... |
| Find: text | The result | That is Text mode: it searches the file's text itself - comments and Strings included - never what the compiler knows. Match case and Whole word narrow it further; the next lesson uses a regular expression to search and replace in one pass. |
| Find: regex replace | Find: regex replace | The find bar's replace row can use a regular expression, whose parenthesised groups the replacement can reorder with $1, $2 and so on. doubled() computes price * 2 - this lesson rewrites it to 2 * price. To play it in the IDE: Help > Lessons > Finding…, or ek9 -ide -lesson find-regex-replace. The ... |
| Find: regex replace | Step 1: Open Replace | Choose Edit > Replace… The EK9 IDE once this is done: Choose Edit > Replace… |
| Find: regex replace | Step 2: A regular expression | Turn on the regular expression toggle (.*), then type (\w+) * (\d) into the field - a word, then * , then a digit, each side held in its own group. One match. The EK9 IDE once this is done: Turn on the regular expression toggle (.*), then type (\w+) * (\d) into the field - a word, then * , then a ... |
| Find: regex replace | Step 3: Replace with a capture group | Type $2 * $1 into the Replace field - the digit first, then the word: the two groups swapped. Choose Replace All. The EK9 IDE once this is done: Type $2 * $1 into the Replace field - the digit first, then the word Text mode changes this file's buffer, not yet saved. Choose File > Save. The EK9 ... |
| Find: regex replace | The result | That is a regular expression's capture groups used in the replacement: price * 2 read, and reordered into 2 * price. Replace changes only the current match; Replace All - just used - changes every match in the file. Text mode edits the buffer, so the file is saved before it is really changed. |
| Find: symbols | Find: symbols | Text mode searches the file's text; Symbols mode asks the last compile for names of the kinds you choose. total here is a class, a field, a method (subtotal), a local, and words inside a comment and a String - only the compiler-known ones survive the switch. To play it in the IDE: Help > Lessons ... |
| Find: symbols | Step 1: Text mode, for contrast | Choose Edit > Find… The EK9 IDE once this is done: Choose Edit > Find… Type total. In Text mode every one of the 15 places matches, comment and String included. The EK9 IDE once this is done: Type total |
| Find: symbols | Step 2: Switch to Symbols | Choose Symbols. The comment and the String drop out, and subtotal counts once, as the method it is, not as a text match on part of its name: 12 matches. The EK9 IDE once this is done: Choose Symbols |
| Find: symbols | Step 3: The three kind chips | Click the Constructs chip to turn it off - the class Total and the program ShowTotal no longer count: 11. The EK9 IDE once this is done: Click the Constructs chip to turn it off - the class Total and the program ShowTotal no longer count Click the Variables chip too, leaving only Members - the ... |
| Find: symbols | Step 4: Declared, Read, Written | Turn off Read, leaving Declared and Written - the field's one read, and the method's own call, drop out: 3. The EK9 IDE once this is done: Turn off Read, leaving Declared and Written - the field's one read, and the method's own call, drop out Turn off Written too, leaving only Declared - the ... |
| Find: symbols | The result | That is Symbols mode: it asks the last compile, never the text, so a comment or a String never matches, and a name is found and classified by what it IS - a construct, a member or a variable - each with its own chip and dropdown, then narrowed by whether it is declared, read or written. Replace, ... |
| Replace: symbols | Replace: symbols | Replace in Symbols mode does not edit text: it renames the symbol Find found, everywhere it is used, through the same compile-checked preview Rename Symbol uses. Here it is the running total ShowTotal keeps in its own local, named total. To play it in the IDE: Help > Lessons > Finding…, or ek9 ... |
| Replace: symbols | Step 1: Find the local | Choose Edit > Replace… The EK9 IDE once this is done: Choose Edit > Replace… Choose Symbols. The EK9 IDE once this is done: Choose Symbols Type total. The EK9 IDE once this is done: Type total Turn off the Constructs chip, then the Members chip, leaving only Variables - just the local remains: 4 ... |
| Replace: symbols | Step 2: Rename it | Type runningTotal into the new-name field. The EK9 IDE once this is done: Type runningTotal into the new-name field Choose Rename. Even though only one match is selected, the whole symbol is renamed - all 4 places, not just that one. The EK9 IDE once this is done: Choose Rename |
| Replace: symbols | Step 3: Preview and apply | The preview shows every place total becomes runningTotal. Choose Apply. |
| Replace: symbols | The result | That is Replace in Symbols mode: every one of the local's 4 places changed together, in one compile-checked preview - never just the match you clicked, the way Text mode's Replace only touches the text at hand. AI assistants use the same ek9_rename_symbol tool. The EK9 IDE when the lesson has ... |
| Replace: symbols | Where this lesson comes from | For AI assistants - the MCP tool ek9_rename_symbol. |
| Find in Project | Find in Project | Edit > Find in Project… opens the find bar at Project scope, every search listed in the Find Results tab. total is in shop.ek9, in receipt.ek9 (the same module), and in till.ek9 (a module of its own). To play it in the IDE: Help > Lessons > Finding…, or ek9 -ide -lesson find-in-project. The EK9 ... |
| Find in Project | Step 1: Open Find in Project | Choose Edit > Find in Project… The EK9 IDE once this is done: Choose Edit > Find in Project… Type total. The Find Results tab lists 27 matches in 3 files - the whole project. The EK9 IDE once this is done: Type total |
| Find in Project | Step 2: List, and jump to a result | Choose the Problems tab, to put Find Results away. The EK9 IDE once this is done: Choose the Problems tab, to put Find Results away Choose List, in the find bar. The Find Results tab comes forward again. The EK9 IDE once this is done: Choose List, in the find bar Click one of till.ek9's own ... |
| Find in Project | Step 3: Narrow to Module | Change the scope to Module. till.ek9 - a module of its own - drops out: 23 matches in 2 files. The EK9 IDE once this is done: Change the scope to Module |
| Find in Project | Step 4: Narrow to File | Change the scope to File. receipt.ek9 drops out too, leaving the open file alone: 15 matches in 1 file. The EK9 IDE once this is done: Change the scope to File |
| Find in Project | The result | That is scope: Project searches the whole workspace, Module just the files of one module, File the open file alone - till.ek9, a module of its own, is the first to drop out narrowing down. Every search lists in the Find Results tab; List brings it forward again, and a result's own click opens it. |
| Find your way | Find your way | Find Construct… jumps straight to a class, function or program by name, anywhere in the project. Find References jumps the other way - from a symbol to every place it is used. To play it in the IDE: Help > Lessons > Finding…, or ek9 -ide -lesson find-your-way. The EK9 IDE as the lesson opens |
| Find your way | Step 1: Find Construct… | Choose Navigate > Find Construct… The EK9 IDE once this is done: Choose Navigate > Find Construct… Type Total. The EK9 IDE once this is done: Type Total Click Total, the class. The editor jumps to its declaration. The EK9 IDE once this is done: Click Total, the class |
| Find your way | Step 2: Find References | Put the caret on the total field's own declaration, on line 7. The EK9 IDE once this is done: Put the caret on the total field's own declaration, on line 7 Choose Navigate > Find References. The References pane lists its declaration, a write and a read. The EK9 IDE once this is done: Choose ... |
| Find your way | The result | Find Construct jumps to a class, function or program by name, anywhere in the project; Find References jumps from a symbol to every place it is used. Neither looks inside text - both ask the compiler, the way Symbols mode does. |
| Chapter 16: a class, built | Chapter 16: a class, built | Chapter 16 builds a class: Counter, counting ticks, and the program that runs it three times. The IDE's own tools make the structure - the class, the field's declaration, each method's whole signature, the program's shell - so what is left to type is only the logic no tool can write: what tick ... |
| Chapter 16: a class, built | Step 1: A class | Choose Code > New Construct > Class… The EK9 IDE once this is done: Choose Code > New Construct > Class… Counter is the class's name. Closed is already selected - EK9's default: a class is closed to extension unless it says 'as open' or 'as abstract'. Type Counter and choose Preview. The EK9 IDE ... |
| Chapter 16: a class, built | Step 2: A field | Right-click the Counter line and choose Add Field… The EK9 IDE once this is done: Right-click the Counter line and choose Add Field… Type count as Integer: 0 - a field, its type, and the value it starts with. Choose OK. The EK9 IDE just before choosing OK: Type count as Integer The preview shows ... |
| Chapter 16: a class, built | Step 3: tick — and its logic | Right-click the Counter line and choose Add Method… The EK9 IDE once this is done: Right-click the Counter line and choose Add Method… tick is the method's name - no return, no parameters, not pure: it changes count. Type tick and choose Apply. The EK9 IDE just before choosing Apply: tick is the ... |
| Chapter 16: a class, built | Step 4: total — and its logic | Right-click the Counter line and choose Add Method… The EK9 IDE once this is done: Right-click the Counter line and choose Add Method… total is the name, Integer the return type, and pure ticked - total only reads count, it changes nothing. Fill them in and choose Apply. The EK9 IDE just before ... |
| Chapter 16: a class, built | Step 5: The program | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Show is the program's name - no application to bind, no parameters, nothing injected: the plain shape every Getting Started program starts from. Type Show and choose Preview. The EK9 IDE ... |
| Chapter 16: a class, built | Step 6: Run it | Choose Run > Run Program… The EK9 IDE once this is done: Choose Run > Run Program… The project's only program is already chosen. Choose Run. clicks so far: 3 - tick() ran three times, and total() reads count back as an Integer. Choose Close. The EK9 IDE just before choosing Close: clicks so far |
| Chapter 16: a class, built | The result | Counter.ek9 now reads exactly as chapter 16 of Getting Started with EK9 shows it: a class the tools built, logic you typed. The same four tools - ek9_new_construct, ek9_add_field, ek9_add_method, ek9_add_program - are what an AI assistant calls to do the same thing. The EK9 IDE when the lesson ... |
| Chapter 16: a class, built | Where this lesson comes from | For AI assistants - the MCP tool ek9_new_construct, ek9_add_field, ek9_add_method, ek9_add_program. |
| Chapter 4: a function, built | Chapter 4: a function, built | Chapter 4 meets a function with nothing to return: announce, which prints a greeting and hands nothing back, and the program that calls it twice. Leaving out a function's '<-' line is how EK9 says "returns nothing" - there is no separate keyword for it. The IDE's own tools make the structure - ... |
| Chapter 4: a function, built | Step 1: A function | Choose Code > New Construct > Function… The EK9 IDE once this is done: Choose Code > New Construct > Function… announce is the function's name - doSomething hints that a function's name should say what it does. Add one parameter, name as String, and choose Preview. The EK9 IDE just before ... |
| Chapter 4: a function, built | Step 2: Its comment, and its logic | Select the announce() line, and above it type a blank line and //No '<-' line: this function does its work and returns nothing. - why there is no '<-' line. Saves when typed. The EK9 IDE once this is done: Select the announce() line, and above it type a blank line and //No '<-' line Select the ... |
| Chapter 4: a function, built | Step 3: The program | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Demo is the program's name - no application to bind, no parameters, nothing injected. Type Demo and choose Preview. The EK9 IDE just before choosing Preview: Demo is the program's name - ... |
| Chapter 4: a function, built | Step 4: Run it | Choose Run > Run Program… The EK9 IDE once this is done: Choose Run > Run Program… The project's only program is already chosen. Choose Run. Hello, Ada then Hello, Grace - announce ran once for each name Demo called it with. Choose Close. The EK9 IDE just before choosing Close: Hello, Ada then ... |
| Chapter 4: a function, built | The result | Announce.ek9 now reads exactly as chapter 4 of Getting Started with EK9 shows it: a function with no return value - leaving out the '<-' line says it - built by the tools, its logic and the teaching line above it typed. The same two tools - ek9_new_construct and ek9_add_program - are what an AI ... |
| Chapter 4: a function, built | Where this lesson comes from | For AI assistants - the MCP tool ek9_new_construct, ek9_add_program. |
| Chapter 14: an enumeration, built | Chapter 14: an enumeration, built | Chapter 14 makes an enumeration: Day, a fixed set of named values that comes with printing, comparing and build-from-text for free - then a kindOf function that switches on it, and a Week program that prints every day. The IDE's own tools make the structure - the enumeration and its seven values ... |
| Chapter 14: an enumeration, built | Step 1: An enumeration | Choose Code > New Construct > Type > Enumeration… The EK9 IDE once this is done: Choose Code > New Construct > Type > Enumeration… Day is the enumeration's name. Add each of the seven days as a value, in order - Monday through Sunday - then choose Preview. The EK9 IDE just before choosing ... |
| Chapter 14: an enumeration, built | Step 2: kindOf — and its logic | Choose Code > New Construct > Function… The EK9 IDE once this is done: Choose Code > New Construct > Function… kindOf is the function's name. Add one parameter, day of type Day, set Returns to String, and tick pure. Choose Preview. The EK9 IDE just before choosing Preview: kindOf is the ... |
| Chapter 14: an enumeration, built | Step 3: The program — and its logic | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Week is the program's name - no application to bind, no parameters, nothing injected. Type Week and choose Preview. The EK9 IDE just before choosing Preview: Week is the program's name - ... |
| Chapter 14: an enumeration, built | Step 4: Run it | Choose Run > Run Program… The EK9 IDE once this is done: Choose Run > Run Program… The project's only program is already chosen. Choose Run. Monday is a weekday ... Saturday is a weekend ... Sunday is a weekend - kindOf answers for every day, and the switch never had to guess. Choose Close. The ... |
| Chapter 14: an enumeration, built | The result | Days.ek9 now reads exactly as chapter 14 of Getting Started with EK9 shows it: an enumeration the tools built in one call, with the function and program that use it, logic you typed. The same three tools - ek9_new_construct (twice: 'type'/'enumeration' and 'function') and ek9_add_program - are ... |
| Chapter 14: an enumeration, built | Where this lesson comes from | For AI assistants - the MCP tool ek9_new_construct, ek9_add_program. |
| Chapter 14: a record, built | Chapter 14: a record, built | Chapter 14 gives a point on a grid, x and y, its own record: built complete in one step, or blank and filled in afterwards, then compared and printed. The IDE's own tools make the structure - the record, each field's declaration, both constructors' whole signatures, moveTo's whole signature - so ... |
| Chapter 14: a record, built | Step 1: A record, with its fields | Choose Code > New Construct > Record… The EK9 IDE once this is done: Choose Code > New Construct > Record… Coord is the record's name. Add x and y, both Integer, each given a starting Value of Integer() - a freshly made but unset Integer - so the record needs no constructor of its own yet. Choose ... |
| Chapter 14: a record, built | Step 2: Building it blank, then complete — and its logic | Right-click the Coord line and choose Add Constructor > No-Arg (default, pure) - the compiler's own standard version, which leaves every field unset. The EK9 IDE once this is done: Right-click the Coord line and choose Add Constructor > No-Arg (default, pure) - the compiler's own standard ... |
| Chapter 14: a record, built | Step 3: moveTo — and its logic | Choose Code > New Construct > Function… The EK9 IDE once this is done: Choose Code > New Construct > Function… moveTo is the function's name - it fills in a blank Coord afterwards. Add three parameters: point of type Coord, toX as Integer, toY as Integer. No return - moveTo changes the Coord it ... |
| Chapter 14: a record, built | Step 4: operator $ — and its logic, then default <=> | Right-click the Coord line and choose Add Operator > $ (string) > skeleton. The EK9 IDE once this is done: Right-click the Coord line and choose Add Operator > $ (string) > skeleton Select the stub line and type $'s own text form - just the two numbers in parentheses, no type name. Saves when ... |
| Chapter 14: a record, built | Step 5: The program — and its logic | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Show is the program's name - no application to bind, no parameters, nothing injected. Type Show and choose Preview. The EK9 IDE just before choosing Preview: Show is the program's name - ... |
| Chapter 14: a record, built | Step 6: Run it | Choose Run > Run Program… The EK9 IDE once this is done: Choose Run > Run Program… The project's only program is already chosen. Choose Run. origin = (2, 3), its x is 2 - origin == twin? true, origin == faraway? false - a blank Coord is made (set? false), then after moveTo: (5, 6) (set? true). ... |
| Chapter 14: a record, built | The result | Coord.ek9 now reads exactly as chapter 14 of Getting Started with EK9 shows it: a record built either complete (Coord(2, 3)) or blank and filled in later (Coord(), then moveTo) - built by the tools, logic you typed. ek9_new_construct, ek9_add_field, ek9_add_constructor and ek9_add_operator - ... |
| Chapter 14: a record, built | Where this lesson comes from | For AI assistants - the MCP tool ek9_new_construct, ek9_add_constructor, ek9_add_operator, ek9_add_program. |
| Create Dynamic Function | Create Dynamic Function | Create Dynamic Function authors a closure - a local variable holding a small function, declared where you are, with no construct of its own to name - extending a base function you pick; the compiler validates the result in the same preview every refactoring opens. Here Checker has nothing to ... |
| Create Dynamic Function | Step 1: Where it goes | Put the caret at the end of the threshold <- 5 line - the closure is inserted straight after it. The EK9 IDE once this is done: Put the caret at the end of the threshold <- 5 line - the closure is inserted straight after it |
| Create Dynamic Function | Step 2: Create the closure | Right-click it - or choose Refactor > Refactor This… - and choose Create Dynamic Function…. Name the variable isPositive, pick Predicate of Integer as the base function - its parameter t and return r appear read-only below - type r: t > 0 as the body, and choose Preview. The EK9 IDE just before ... |
| Create Dynamic Function | Step 3: Preview and apply | The preview shows the closure; then the IDE formats the file it changed. Choose Apply. The EK9 IDE just before choosing Apply: The preview shows the closure; then the IDE formats the file it changed |
| Create Dynamic Function | Step 4: Use it | A closure never called is a local EK9 refuses (E08090) - replace stdout.println($threshold) with stdout.println($isPositive(threshold)) and save. The EK9 IDE once this is done: A closure never called is a local EK9 refuses (E08090) - replace stdout.println($threshold) with ... |
| Create Dynamic Function | The result | That is Create Dynamic Function: isPositive is a closure extending Predicate of Integer, its body r: t > 0 - t and r are the base's own parameter and return names, shown read-only once the base is picked - and threshold's println now calls it. Leave the body empty and the tool scaffolds a //AI ... |
| Create Dynamic Function | Where this lesson comes from | Answers - ek9 -q and the IDE's Answers tab: 52.For AI assistants - the MCP tool ek9_create_dynamic_function. |
| Create Dynamic Class | Create Dynamic Class | Create Dynamic Class authors a class - a local variable holding a small object, declared where you are, with no construct of its own to name - implementing one or more traits you pick, extending a generic base, or naming a module-level tuple type; the compiler validates the result in the same ... |
| Create Dynamic Class | Step 1: Where it goes | Put the caret at the end of the prefix <- "item" line - the class is inserted straight after it. The EK9 IDE once this is done: Put the caret at the end of the prefix <- "item" line - the class is inserted straight after it |
| Create Dynamic Class | Step 2: Create the class | Right-click it - or choose Refactor > Refactor This… - and choose Create Dynamic Class…. Name the variable d, add a trait row named Describable - trait is already the chosen form - choose Generate trait methods to stub describe(), and choose Preview. The EK9 IDE just before choosing Preview: ... |
| Create Dynamic Class | Step 3: Preview and apply | The preview shows the class; then the IDE formats the file it changed. Choose Apply. The EK9 IDE just before choosing Apply: The preview shows the class; then the IDE formats the file it changed |
| Create Dynamic Class | Step 4: Use it | An instance never used is a local EK9 refuses (E08090) - replace stdout.println(prefix) with stdout.println(prefix + d.describe()) and save. The EK9 IDE once this is done: An instance never used is a local EK9 refuses (E08090) - replace stdout.println(prefix) with stdout.println(prefix + ... |
| Create Dynamic Class | The result | That is Create Dynamic Class: d is an anonymous class implementing Describable, its one abstract method describe() stubbed by Generate trait methods with a //AI: complete method lead - and prefix's println now reads it too. The same Form selector offers tuple (a named module-level type, captures ... |
| Create Dynamic Class | Where this lesson comes from | Answers - ek9 -q and the IDE's Answers tab: 1126.For AI assistants - the MCP tool ek9_create_dynamic_class. |
| Chapter 3: a loop, reshaped | Chapter 3: a loop, reshaped | Chapter 3 meets repetition with Countdown: print 5, 4, 3, 2, 1, then Lift off. Rather than type the loop straight away, this lesson writes a plain version first - print the count once, the way chapter 3 itself starts - and then uses Surround With to fold the repeating part under a while head, the ... |
| Chapter 3: a loop, reshaped | Step 1: The program | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Countdown is the program's name - no application to bind, no parameters, nothing injected. Type Countdown and choose Preview. The EK9 IDE just before choosing Preview: Countdown is the ... |
| Chapter 3: a loop, reshaped | Step 2: A plain start | Select the stub, from ready <- true down to its //AI line, and type the plain version: a Stdout, countdown starting at 5, one print, then Lift off - said once, not yet repeated. Saves when typed. The EK9 IDE once this is done: Select the stub, from ready <- true down to its //AI line, and type ... |
| Chapter 3: a loop, reshaped | Step 3: Loop it with Surround With | Put the caret on the countdown print, right-click - or choose Refactor > Refactor This… - and choose Surround With ▸ while. The EK9 IDE once this is done: Put the caret on the countdown print, right-click - or choose Refactor > Refactor This… - and choose Surround With ▸ while Select the stub, ... |
| Chapter 3: a loop, reshaped | Step 4: Run it | Choose Run > Run Program… The EK9 IDE once this is done: Choose Run > Run Program… The project's only program is already chosen. Choose Run. 5... then 4... 3... 2... 1... then Lift off - the loop ran while countdown was still above zero, and stopped the moment it was not. Choose Close. The EK9 ... |
| Chapter 3: a loop, reshaped | The result | Countdown.ek9 now reads exactly as chapter 3 of Getting Started with EK9 shows it: a program that counts down and stops. The plain version you typed first printed the count once; Surround With folded it under a loop head, re-indenting it for you, and the condition you typed over its placeholder ... |
| Chapter 3: a loop, reshaped | Where this lesson comes from | For AI assistants - the MCP tool ek9_new_construct, ek9_surround_with. |
| Chapter 17: an abstract type and its subtypes, built | Chapter 17: an abstract type and its subtypes, built | Chapter 17 builds a type hierarchy: Shape, an abstract contract with no body of its own, and two subtypes - Circle and Rectangle - that each complete it in their own way. The IDE's own tools make the structure - the constant, the abstract class and its two abstract methods, each subtype's field, ... |
| Chapter 17: an abstract type and its subtypes, built | Step 1: A constant | Choose Code > New Construct > Constant… The EK9 IDE once this is done: Choose Code > New Construct > Constant… PI is the constant's name, and 3.14159 its value - a Float literal, typed into the Value field below it. Type PI, then the value, and choose Preview. The EK9 IDE just before choosing ... |
| Chapter 17: an abstract type and its subtypes, built | Step 2: An abstract type | Choose Code > New Construct > Class… The EK9 IDE once this is done: Choose Code > New Construct > Class… Shape is the class's name. Choose Abstract, not Closed - Shape is a contract, not a thing: it will declare what a shape must answer, never how. Type Shape, choose Abstract, and choose Preview. ... |
| Chapter 17: an abstract type and its subtypes, built | Step 3: Circle — a subtype | Choose Code > New Construct > Class… The EK9 IDE once this is done: Choose Code > New Construct > Class… Circle is the name, closed (the default) is fine - Circle itself need not be extended further. Type Shape into Extends, naming the contract Circle completes. Type Circle, fill in Extends, and ... |
| Chapter 17: an abstract type and its subtypes, built | Step 4: Rectangle — another subtype | Choose Code > New Construct > Class… The EK9 IDE once this is done: Choose Code > New Construct > Class… Rectangle is the name, closed is fine, and Shape is the same Extends as Circle's. Type Rectangle, fill in Extends, and choose Preview. The EK9 IDE just before choosing Preview: Rectangle is ... |
| Chapter 17: an abstract type and its subtypes, built | Step 5: The program | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Show is the program's name - no application to bind, no parameters, nothing injected. Type Show and choose Preview. The EK9 IDE just before choosing Preview: Show is the program's name - ... |
| Chapter 17: an abstract type and its subtypes, built | Step 6: Run it | Choose Run > Run Program… The EK9 IDE once this is done: Choose Run > Run Program… The project's only program is already chosen. Choose Run. a circle has area 12.56636 then a rectangle has area 12.0 - one loop, one call to area() each time, and the right formula runs for each shape without ever ... |
| Chapter 17: an abstract type and its subtypes, built | The result | Shapes.ek9 now reads exactly as chapter 17 of Getting Started with EK9 shows it: an abstract Shape the tools built with two abstract methods and no body to type, two subtypes each with its own field, constructor and overrides, and a program that holds both in one List of Shape - logic you typed. ... |
| Chapter 17: an abstract type and its subtypes, built | Where this lesson comes from | For AI assistants - the MCP tool ek9_new_construct, ek9_add_field, ek9_add_constructor, ek9_add_method, ek9_add_program. |
| Chapter 18: traits and delegation, built | Chapter 18: traits and delegation, built | Chapter 18 builds a trait, View, with no state of its own - and two classes that take it on two different ways: Home implements it, Framed delegates to a field it holds. The IDE's own tools make the structure - the trait's shell, each method's whole signature, the trait adoption itself, the ... |
| Chapter 18: traits and delegation, built | Step 1: A trait | Choose Code > New Construct > Trait… The EK9 IDE once this is done: Choose Code > New Construct > Trait… View is the trait's name. Type View and choose Preview. The EK9 IDE just before choosing Preview: View is the trait's name The preview shows View about to be written - a shell, nothing inside ... |
| Chapter 18: traits and delegation, built | Step 2: Home — implementing it | Choose Code > New Construct > Class… The EK9 IDE once this is done: Choose Code > New Construct > Class… Home is the class's name. Type Home and choose Preview. The EK9 IDE just before choosing Preview: Home is the class's name The preview shows Home about to be written. Choose Apply. The EK9 IDE ... |
| Chapter 18: traits and delegation, built | Step 3: Framed — the field and delegation | Choose Code > New Construct > Class… The EK9 IDE once this is done: Choose Code > New Construct > Class… Framed is the class's name. Type Framed and choose Preview. The EK9 IDE just before choosing Preview: Framed is the class's name The preview shows Framed about to be written. Choose Apply. The ... |
| Chapter 18: traits and delegation, built | Step 4: Framed — construction and body | Select the stub, from Framed() as pure down to this.inner :=? inner, and type Framed's real one: a renamed parameter, viewToWrap, a require guard, and the assignment it guards. Saves when typed. The EK9 IDE once this is done: Select the stub, from Framed() as pure down to this.inner :=? inner, ... |
| Chapter 18: traits and delegation, built | Step 5: The program | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Show is the program's name - no application to bind, no parameters, nothing injected. Type Show and choose Preview. The EK9 IDE just before choosing Preview: Show is the program's name - ... |
| Chapter 18: traits and delegation, built | Step 6: Run it | Choose Run > Run Program… The EK9 IDE once this is done: Choose Run > Run Program… The project's only program is already chosen. Choose Run. title: Home, body: *** Welcome *** - title passes straight through the delegation, body is wrapped. Choose Close. The EK9 IDE just before choosing Close: title |
| Chapter 18: traits and delegation, built | The result | Delegate.ek9 now reads exactly as chapter 18 of Getting Started with EK9 shows it: a trait the tools built, Home implementing it and Framed delegating to a field it holds, logic you typed. The same tools - ek9_new_construct, ek9_add_method, ek9_adopt_trait, ek9_add_field, ek9_add_constructor, ... |
| Chapter 18: traits and delegation, built | Where this lesson comes from | For AI assistants - the MCP tool ek9_new_construct, ek9_add_method, ek9_adopt_trait, ek9_add_field, ek9_add_constructor, ek9_add_operator, ek9_add_program. |
| Chapter 21: operators, built | Chapter 21: operators, built | Chapter 21 gives a small vector its own + (add two vectors) and $ (how it prints), then defaults the rest: <=> for comparison, ? for whether it is set. The IDE's own tools make the structure - the record, each field's declaration, the constructor's and +'s whole signature - so what is left to ... |
| Chapter 21: operators, built | Step 1: A record, with its fields | Choose Code > New Construct > Record… The EK9 IDE once this is done: Choose Code > New Construct > Record… Vec2 is the record's name. Add x and y, both Integer, each given a starting Value of Integer() - a freshly made but unset Integer - so the record needs no constructor of its own yet. Choose ... |
| Chapter 21: operators, built | Step 2: Its constructor — and its logic | Right-click the Vec2 line and choose Add Constructor > From All Fields (pure). The EK9 IDE once this is done: Right-click the Vec2 line and choose Add Constructor > From All Fields (pure) Select the stub, from Vec2() as pure down to its last assignment, and type the constructor's whole job: ... |
| Chapter 21: operators, built | Step 3: operator + — a custom operator, and its logic | Right-click the Vec2 line and choose Add Operator > Custom Operator… The EK9 IDE once this is done: Right-click the Vec2 line and choose Add Operator > Custom Operator… is not one of the eight operators with their own menu entry - type it here, in Custom Operator…'s one field. Choose OK. The EK9 ... |
| Chapter 21: operators, built | Step 4: operator $ — and its logic | Right-click the Vec2 line and choose Add Operator > $ (string) > skeleton. The EK9 IDE once this is done: Right-click the Vec2 line and choose Add Operator > $ (string) > skeleton Select the stub line and type $'s own text form - just the two numbers in parentheses, no type name. Saves when ... |
| Chapter 21: operators, built | Step 5: default operator <=> | Right-click the Vec2 line and choose Add Operator > <=> (compare) > default. The EK9 IDE once this is done: Right-click the Vec2 line and choose Add Operator > <=> (compare) > default |
| Chapter 21: operators, built | Step 6: The program | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Show is the program's name - no application to bind, no parameters, nothing injected. Type Show and choose Preview. The EK9 IDE just before choosing Preview: Show is the program's name - ... |
| Chapter 21: operators, built | Step 7: Run it | Choose Run > Run Program… The EK9 IDE once this is done: Choose Run > Run Program… The project's only program is already chosen. Choose Run. (1, 2) + (3, 4) = (4, 6) - a == twin? true, a == b? false. Choose Close. The EK9 IDE just before choosing Close: (1, 2) + (3, 4) = (4, 6) - a == twin? true, ... |
| Chapter 21: operators, built | The result | Vectors.ek9 now reads exactly as chapter 21 of Getting Started with EK9 shows it: a record with its own + and $, default operator <=> and ? for the rest - built by the tools, logic you typed. ek9_add_operator - called here through a new Custom Operator… dialog, the same door an AI assistant ... |
| Chapter 21: operators, built | Where this lesson comes from | For AI assistants - the MCP tool ek9_new_construct, ek9_add_constructor, ek9_add_operator, ek9_add_program. |
| Chapter 21: promotion, #^ | Chapter 21: promotion, #^ | An Integer becomes a Float wherever a Float is wanted - 7 becomes 7.0 - through an operator, #^ (promote). Chapter 21 gives a type of your own one too: a Celsius that promotes itself to a Fahrenheit Float. The IDE's tools make the structure - the record, its field, the constructor and each ... |
| Chapter 21: promotion, #^ | Step 1: A record, with its field | Choose Code > New Construct > Record… The EK9 IDE once this is done: Choose Code > New Construct > Record… Celsius is the record's name. Add degrees, a Float, given a starting Value of Float() - a freshly made but unset Float - so the record needs no constructor of its own yet. Choose Preview. ... |
| Chapter 21: promotion, #^ | Step 2: Its constructor — and its logic | Right-click the Celsius line and choose Add Constructor > From All Fields (pure). The EK9 IDE once this is done: Right-click the Celsius line and choose Add Constructor > From All Fields (pure) Select the stub, from Celsius() as pure down to its assignment, and type the constructor's whole job: ... |
| Chapter 21: promotion, #^ | Step 3: operator $ — and its logic | Right-click the Celsius line and choose Add Operator > $ (string) > skeleton. The EK9 IDE once this is done: Right-click the Celsius line and choose Add Operator > $ (string) > skeleton Select the stub line and type $'s own text form - the degrees and a C, no type name. Saves when typed. The EK9 ... |
| Chapter 21: promotion, #^ | Step 4: operator #^ — promotion, and its logic | Right-click the Celsius line and choose Add Operator > Custom Operator… The EK9 IDE once this is done: Right-click the Celsius line and choose Add Operator > Custom Operator… #^ is not one of the eight operators with their own menu entry - type it here, in Custom Operator…'s one field. Choose OK. ... |
| Chapter 21: promotion, #^ | Step 5: The program — two promotions | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Show is the program's name - no application to bind, no parameters, nothing injected. Type Show and choose Preview. The EK9 IDE just before choosing Preview: Show is the program's name - ... |
| Chapter 21: promotion, #^ | Step 6: Run it | Choose Run > Run Program… The EK9 IDE once this is done: Choose Run > Run Program… The project's only program is already chosen. Choose Run. 100.0C is 212.0F - Celsius's own #^ - and 7 promoted to 7.0, Integer's. Choose Close. The EK9 IDE just before choosing Close: 100.0C is 212.0F - Celsius's ... |
| Chapter 21: promotion, #^ | The result | Celsius.ek9 now reads exactly as chapter 21 of Getting Started with EK9 shows it: a record with its own $ and a #^ that promotes it to a Fahrenheit Float, and a program where a Celsius and an Integer are each promoted to a Float - one #^ step each, no casts. Built by the tools, logic you typed. ... |
| Chapter 21: promotion, #^ | Where this lesson comes from | For AI assistants - the MCP tool ek9_new_construct, ek9_add_constructor, ek9_add_operator, ek9_add_program. |
| Chapter 19: a component, built | Chapter 19: a component, built | Chapter 19 builds a component: Pricing, an interface hiding the types that work out a price - a TaxTable class and a basePrice function - behind ONE method, totalPrice. The program depends on Pricing alone; it never mentions TaxTable or basePrice. The IDE's own tools make the structure - each ... |
| Chapter 19: a component, built | Step 1: TaxTable — and surcharge | Choose Code > New Construct > Class… The EK9 IDE once this is done: Choose Code > New Construct > Class… TaxTable is the class's name - a helper behind the interface, never mentioned by the program. Type TaxTable and choose Preview. The EK9 IDE just before choosing Preview: TaxTable is the ... |
| Chapter 19: a component, built | Step 2: basePrice | Choose Code > New Construct > Function… The EK9 IDE once this is done: Choose Code > New Construct > Function… basePrice is the function's name - no parameters, Money the return type. Fill them in and choose Preview. The EK9 IDE just before choosing Preview: basePrice is the function's name - no ... |
| Chapter 19: a component, built | Step 3: Pricing — the interface | Choose Code > New Construct > Component… The EK9 IDE once this is done: Choose Code > New Construct > Component… Pricing is the component's name - the interface everything else hides behind. Choose Abstract under Extensibility, then Preview. The EK9 IDE just before choosing Preview: Pricing is ... |
| Chapter 19: a component, built | Step 4: StandardPricing — and its logic | Choose Code > New Construct > Component… The EK9 IDE once this is done: Choose Code > New Construct > Component… StandardPricing is the component's name - left Closed, nothing else. Type Pricing into Extends, naming the interface StandardPricing completes. Type StandardPricing, fill in Extends, ... |
| Chapter 19: a component, built | Step 5: The program | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Show is the program's name - no application to bind, no parameters, nothing injected. Type Show and choose Preview. The EK9 IDE just before choosing Preview: Show is the program's name - ... |
| Chapter 19: a component, built | Step 6: Run it | Choose Run > Run Program… The EK9 IDE once this is done: Choose Run > Run Program… The project's only program is already chosen. Choose Run. total price: 12.00#GBP - the base price plus the surcharge, worked out behind the Pricing interface the program never looks past. Choose Close. The EK9 IDE ... |
| Chapter 19: a component, built | The result | Pricing.ek9 now reads exactly as chapter 19 of Getting Started with EK9 shows it: a component hiding a class and a function behind an interface, logic you typed - StandardPricing's override arriving WITH the component itself, the moment its Extends names Pricing. The same tools - ... |
| Chapter 19: a component, built | Where this lesson comes from | For AI assistants - the MCP tool ek9_new_construct, ek9_add_method, ek9_add_program. |
| Chapter 5: tests, built | Chapter 5: tests, built | Chapter 5 asks two questions: how do you know a function gives the right answer, and how do you run one on its own when all you have run so far is a program? The answer to both is a test: square and cube, two pure functions, and the @Test programs that check them, kept in a dev/ directory of ... |
| Chapter 5: tests, built | Step 1: square — a pure function | Choose Code > New Construct > Function… The EK9 IDE once this is done: Choose Code > New Construct > Function… square is the function's name. Add one parameter, n of type Integer, set Returns to Integer, and tick pure. Choose Preview. The EK9 IDE just before choosing Preview: square is the ... |
| Chapter 5: tests, built | Step 2: cube — a pure function | Choose Code > New Construct > Function… The EK9 IDE once this is done: Choose Code > New Construct > Function… cube is the function's name. Add one parameter, n of type Integer, set Returns to Integer, and tick pure, as square's were. Choose Preview. The EK9 IDE just before choosing Preview: cube ... |
| Chapter 5: tests, built | Step 3: Where tests live | Open dev/tests.ek9 - already there, with just its own module line. Test code goes in a directory named dev/, kept apart from the code you ship. The EK9 IDE once this is done: Open dev/tests.ek9 - already there, with just its own module line Select the module line, and below it type a references ... |
| Chapter 5: tests, built | Step 4: SquareTest | Choose Code > New Construct > Test… The EK9 IDE once this is done: Choose Code > New Construct > Test… SquareTest is the test's name - a test IS a program, so it is named the same way: no application, no parameters, nothing injected. Type SquareTest and choose Preview. The EK9 IDE just before ... |
| Chapter 5: tests, built | Step 5: CubeTest | Choose Code > New Construct > Test… The EK9 IDE once this is done: Choose Code > New Construct > Test… CubeTest is the name, as plain as SquareTest's. Type CubeTest and choose Preview. The EK9 IDE just before choosing Preview: CubeTest is the name, as plain as SquareTest's The preview shows ... |
| Chapter 5: tests, built | Step 6: Run the tests | Run ▸ Run Tests (⌘T) runs every @Test in the project - SquareTest and CubeTest both - and reports pass or fail, the same as ek9 -t at the command line. Choose Run Tests. The EK9 IDE once this is done: Run ▸ Run Tests (⌘T) runs every @Test in the project - SquareTest and CubeTest both - and ... |
| Chapter 5: tests, built | Step 7: Generate Edge-Case Tests | Choose Code > Generate > Edge-Case Tests (whole file)… The EK9 IDE once this is done: Choose Code > Generate > Edge-Case Tests (whole file)… The dialog already has sensible defaults - the output routed to dev/, 200 candidates, a random seed. Choose Generate. However many of the 200 candidates ... |
| Chapter 5: tests, built | The result | maths.ek9 and dev/tests.ek9 now read exactly as chapter 5 of Getting Started with EK9 shows them: two pure functions and the @Test programs that check them, each tool-built, each real claim typed. Run Tests found both passing and shaded every line they covered; Generate Edge-Case Tests then tried ... |
| Chapter 5: tests, built | Where this lesson comes from | For AI assistants - the MCP tool ek9_new_construct, ek9_add_program, ek9_run_tests, ek9_generate_edge_case_tests. |
| Chapter 2: values, reshaped | Chapter 2: values, reshaped | Chapter 2 is about values: names for them, EK9's built-in types, and the idea that a value can be set, unset, or briefly absent. Its own closing example - an unset chosenAge, and later, the arithmetic on it, still unset too - is written here plainer first: one extra name that adds nothing over ... |
| Chapter 2: values, reshaped | Step 1: The program | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Values is the program's name - no application to bind, no parameters, nothing injected. Type Values and choose Preview. The EK9 IDE just before choosing Preview: Values is the program's ... |
| Chapter 2: values, reshaped | Step 2: A plain start | Select the stub, from ready <- true down to its //AI line, and type the book's own lines - name, age, pi, greeting and total, the four prints that follow, the selectedName checks - plainer only at the very end: chosenAge, one extra name, laterOffset, that only gets in the way, and the arithmetic ... |
| Chapter 2: values, reshaped | Step 3: Inline Variable | Put the caret on laterOffset <- 4 - a name that adds nothing over the literal it holds, read only once, on the very next line. The EK9 IDE once this is done: Put the caret on laterOffset <- 4 - a name that adds nothing over the literal it holds, read only once, on the very next line Choose ... |
| Chapter 2: values, reshaped | Step 4: Extract Variable | Select chosenAge + 4 - chosenAge + 4 itself, not the brackets or the ? around it - inside the last println. The EK9 IDE once this is done: Select chosenAge + 4 - chosenAge + 4 itself, not the brackets or the ? around it - inside the last println Choose Refactor > Extract Variable… The EK9 IDE ... |
| Chapter 2: values, reshaped | Step 5: Run it | Choose Run > Run Program… The EK9 IDE once this is done: Choose Run > Run Program… The project's only program is already chosen. Choose Run. Hello, Ada, then In four years Ada will be 40, then Ada is 36 years old and pi is roughly 3.142 - then selectedName? reads false, then true once it is given ... |
| Chapter 2: values, reshaped | The result | Values.ek9 now reads exactly as chapter 2 of Getting Started with EK9 shows it. greeting and total were typed straight in - ordinary logic, not a tool's job - but the chapter's own closing example, chosenAge and later, started plainer: a stray local, laterOffset, saying nothing 4 did not, written ... |
| Chapter 2: values, reshaped | Where this lesson comes from | For AI assistants - the MCP tool ek9_add_program, ek9_inline_variable, ek9_extract_variable. |
| Chapter 12: a pipeline, built | Chapter 12: a pipeline, built | Chapter 12 meets the stream: a pipeline of small stages joined by |, each with one job - filter keeps some values, map changes every one, and the pipeline ends by printing or collecting a result. Numbers keeps the even numbers from 1 to 6, doubles them, and prints what is left - the chapter's own ... |
| Chapter 12: a pipeline, built | Step 1: isEven — a pure function | Choose Code > New Construct > Function… The EK9 IDE once this is done: Choose Code > New Construct > Function… isEven is the function's name. Add one parameter, n of type Integer, set Returns to Boolean, and tick pure. Choose Preview. The EK9 IDE just before choosing Preview: isEven is the ... |
| Chapter 12: a pipeline, built | Step 2: doubleIt — a pure function | Choose Code > New Construct > Function… The EK9 IDE once this is done: Choose Code > New Construct > Function… doubleIt is the function's name. Add one parameter, n of type Integer, set Returns to Integer, and tick pure, as isEven's were. Choose Preview. The EK9 IDE just before choosing Preview: ... |
| Chapter 12: a pipeline, built | Step 3: The program | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Numbers is the program's name - no application to bind, no parameters, nothing injected. Type Numbers and choose Preview. The EK9 IDE just before choosing Preview: Numbers is the program's ... |
| Chapter 12: a pipeline, built | Step 4: Read the pipeline | Put the caret anywhere on the pipeline line - between for and > stdout - then choose Analyse ▸ Pipeline: cursor-anchored, the same way Flow Analysis and Effective API read the construct the caret sits in. The EK9 IDE once this is done: Put the caret anywhere on the pipeline line - between for and ... |
| Chapter 12: a pipeline, built | Step 5: Run it | Choose Run > Run Program… The EK9 IDE once this is done: Choose Run > Run Program… The project's only program is already chosen. Choose Run. 4, then 8, then 12 - the even numbers from 1 to 6, each doubled by the time the pipeline reached stdout. Choose Close. The EK9 IDE just before choosing ... |
| Chapter 12: a pipeline, built | The result | Numbers.ek9 now reads exactly as chapter 12 of Getting Started with EK9 shows it: two pure functions and the pipeline that filters, doubles and prints with them. Analyse ▸ Pipeline decomposed that pipeline stage by stage before it ran - the same decomposition ek9_query_pipeline answers for an AI ... |
| Chapter 12: a pipeline, built | Where this lesson comes from | For AI assistants - the MCP tool ek9_new_construct, ek9_add_program, ek9_query_pipeline. |
| Chapter 10: guards, reshaped | Chapter 10: guards, reshaped | Chapter 10 is about guards: a value declared and checked in one breath, so code only runs once something is known to be set. Rather than type the guard directly, this lesson writes the plainer, two-statement form first - a declaration, then a separate check right after it, chapter 10's own ... |
| Chapter 10: guards, reshaped | Step 1: lookupName | Choose Code > New Construct > Function… The EK9 IDE once this is done: Choose Code > New Construct > Function… lookupName is the function's name - no parameters. Set Returns to String and tick pure. Choose Preview. The EK9 IDE just before choosing Preview: lookupName is the function's name - no ... |
| Chapter 10: guards, reshaped | Step 2: storedName | Choose Code > New Construct > Function… The EK9 IDE once this is done: Choose Code > New Construct > Function… storedName is the function's name - no parameters. Set Returns to String, tick pure, and choose Preview. The EK9 IDE just before choosing Preview: storedName is the function's name - no ... |
| Chapter 10: guards, reshaped | Step 3: messagePrefix | Choose Code > New Construct > Function… The EK9 IDE once this is done: Choose Code > New Construct > Function… messagePrefix is the function's name - no parameters. Set Returns to String, tick pure, and choose Preview. The EK9 IDE just before choosing Preview: messagePrefix is the function's name ... |
| Chapter 10: guards, reshaped | Step 4: Greet — a guard, twice | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Greet is the program's name - no application to bind, no parameters, nothing injected. Type Greet and choose Preview. The EK9 IDE just before choosing Preview: Greet is the program's name ... |
| Chapter 10: guards, reshaped | Step 5: GreetLongNames — a guard with a condition | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… GreetLongNames is the program's name. Type it and choose Preview. The EK9 IDE just before choosing Preview: GreetLongNames is the program's name The preview shows GreetLongNames about to ... |
| Chapter 10: guards, reshaped | Step 6: Echo — the same guard in a 'while' | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Echo is the program's name. Type it and choose Preview. The EK9 IDE just before choosing Preview: Echo is the program's name The preview shows Echo about to be written. Choose Apply. The ... |
| Chapter 10: guards, reshaped | Step 7: Numbered — the same guard before a 'for' | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Numbered is the program's name. Type it and choose Preview. The EK9 IDE just before choosing Preview: Numbered is the program's name The preview shows Numbered about to be written. Choose ... |
| Chapter 10: guards, reshaped | Step 8: Run it | Choose Run > Run Program… The EK9 IDE once this is done: Choose Run > Run Program… Choose Greet from the list, then choose Run. Hello, Ada - lookupName() gave nothing, so its guard never ran; storedName() gave Ada, so its guard did. Choose Close. The EK9 IDE just before choosing Close: Hello, Ada ... |
| Chapter 10: guards, reshaped | The result | Guards.ek9 now reads exactly as chapter 10 of Getting Started with EK9 shows it: three functions a program can ask for a name, and four programs that each declare one, check it is set, and act on it - written here plainer first, a declaration then a separate check right after it - and Lift into ... |
| Chapter 10: guards, reshaped | Where this lesson comes from | For AI assistants - the MCP tool ek9_new_construct, ek9_add_program, ek9_apply_guard_pattern. |
| Chapter 11: Optional and Result, built | Chapter 11: Optional and Result, built | Chapter 11 meets two small containers for uncertainty: Optional, a box that holds a value or none, and Result, a box that holds success or an error. Divide asks safeDivide for a / b and gets back a Result of (Integer, String) rather than a runtime exception - isOk()/ok() on success, ... |
| Chapter 11: Optional and Result, built | Step 1: safeDivide — a pure function returning Result | Choose Code > New Construct > Function… The EK9 IDE once this is done: Choose Code > New Construct > Function… safeDivide is the function's name. Add two parameters, a and b, both Integer, set Returns to Result of (Integer, String), and tick pure. Choose Preview. The EK9 IDE just before choosing ... |
| Chapter 11: Optional and Result, built | Step 2: Divide by zero, with Surround With | Put the caret on the division line, right-click - or choose Refactor > Refactor This… - and choose Surround With ▸ if ... else. The EK9 IDE once this is done: Put the caret on the division line, right-click - or choose Refactor > Refactor This… - and choose Surround With ▸ if .. Select the stub, ... |
| Chapter 11: Optional and Result, built | Step 3: The program | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Div is the program's name - no application to bind, no parameters, nothing injected. Type Div and choose Preview. The EK9 IDE just before choosing Preview: Div is the program's name - no ... |
| Chapter 11: Optional and Result, built | Step 4: Read Result's effective API | Select good, on the line that declares it, then choose Analyse ▸ Effective API: cursor-anchored, the same way Pipeline read chapter 12's stream before it ran. The EK9 IDE once this is done: Select good, on the line that declares it, then choose Analyse ▸ Effective API The pane draws Result of ... |
| Chapter 11: Optional and Result, built | Step 5: Run it | Choose Run > Run Program… The EK9 IDE once this is done: Choose Run > Run Program… The project's only program is already chosen. Choose Run. Answer: 5, then Cannot: cannot divide by zero - the first call succeeded, the second was refused before it ever divided. Choose Close. The EK9 IDE just ... |
| Chapter 11: Optional and Result, built | The result | Divide.ek9 now reads exactly as chapter 11 of Getting Started with EK9 shows it: a pure function that returns a Result rather than risk a division by zero, and a program that only ever reads it after checking which it got. Surround With folded the division itself under an if ... else head before ... |
| Chapter 11: Optional and Result, built | Where this lesson comes from | For AI assistants - the MCP tool ek9_new_construct, ek9_surround_with, ek9_add_program, ek9_query_effective_api. |
| Chapter 15: a constrained type, built | Chapter 15: a constrained type, built | Chapter 15 makes a constrained type: DrivingAge, an Integer narrowed to values 16 to 100 - not any Integer, but one the rule holds to, the same 'illegal states unrepresentable' idea an enumeration gives a fixed set of names. Then a verdict function that takes a DrivingAge, and a Show program that ... |
| Chapter 15: a constrained type, built | Step 1: A constrained type | Choose Code > New Construct > Type > Constrained… The EK9 IDE once this is done: Choose Code > New Construct > Type > Constrained… DrivingAge is the constrained type's name. Choose Integer as its base type, then type its rule, >= 16 and <= 100, into the Constraint field. Choose Preview. The EK9 ... |
| Chapter 15: a constrained type, built | Step 2: verdict — and its logic | Choose Code > New Construct > Function… The EK9 IDE once this is done: Choose Code > New Construct > Function… verdict is the function's name. Add one parameter, age of type DrivingAge, and set Returns to String. Choose Preview. The EK9 IDE just before choosing Preview: verdict is the function's ... |
| Chapter 15: a constrained type, built | Step 3: The program — and its logic | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Show is the program's name - no application to bind, no parameters, nothing injected. Type Show and choose Preview. The EK9 IDE just before choosing Preview: Show is the program's name - ... |
| Chapter 15: a constrained type, built | Step 4: Run it | Choose Run > Run Program… The EK9 IDE once this is done: Choose Run > Run Program… The project's only program is already chosen. Choose Run. 17 is a valid driving age, with next year printing 18 - then 20 is accepted, but 9 and 133 are both rejected as out of range. Choose Close. The EK9 IDE just ... |
| Chapter 15: a constrained type, built | The result | DrivingAge.ek9 now reads exactly as chapter 15 of Getting Started with EK9 shows it: a constrained type the tool built in one call - a base type and a range rule - with the function and program that use it, logic you typed. The same three tools - ek9_new_construct (twice: 'type'/'constrained' and ... |
| Chapter 15: a constrained type, built | Where this lesson comes from | For AI assistants - the MCP tool ek9_new_construct, ek9_add_program. |
| Chapter 7: asking about a type | Chapter 7: asking about a type | Chapter 7 gives real-world values real types: Money, dates and durations, and Dimension - a measurement with a unit, 20cm or 3px. Measures doubles one, widens it by another of the same unit, then adds one of a DIFFERENT unit - centimetres and pixels do not mix, so EK9 gives back not a wrong ... |
| Chapter 7: asking about a type | Step 1: The program | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Measures is the program's name - no application to bind, no parameters, nothing injected. Type Measures and choose Preview. The EK9 IDE just before choosing Preview: Measures is the ... |
| Chapter 7: asking about a type | Step 2: Ask: /h Dimension | Type /h Dimension into the input bar above the editor and choose -> to send it - the same /h this chapter's own types answer to at a terminal. The EK9 IDE once this is done: Type /h Dimension into the input bar above the editor and choose -> to send it - the same /h this chapter's own types ... |
| Chapter 7: asking about a type | Step 3: Ask: Effective API | Select width, on the line that declares it, then choose Analyse ▸ Effective API: cursor-anchored, the same way /h just answered from the input bar instead. The EK9 IDE once this is done: Select width, on the line that declares it, then choose Analyse ▸ Effective API The pane draws Dimension's own ... |
| Chapter 7: asking about a type | Step 4: Run it | Choose Run > Run Program… The EK9 IDE once this is done: Choose Run > Run Program… The project's only program is already chosen. Choose Run. 20.0cm, then 40.0cm doubled, then 25.0cm wider - then 20cm + 3px is set? reads false: centimetres and pixels do not mix. Choose Close. The EK9 IDE just ... |
| Chapter 7: asking about a type | The result | Measures.ek9 now reads exactly as chapter 7 of Getting Started with EK9 shows it: a Dimension doubled, widened by the same unit, and mixed with the wrong one - unset, never a wrong number. /h Dimension and Analyse ▸ Effective API then answered the same question about Dimension two ways - the Help ... |
| Chapter 7: asking about a type | Where this lesson comes from | For AI assistants - the MCP tool ek9_new_construct, ek9_add_program, ek9_help, ek9_query_effective_api. |
| Chapter 8: a text type, built | Chapter 8: a text type, built | Chapter 8 is about keeping translations INSIDE the language, where the compiler can see them. Party is a text type speaking three languages for one birthday message; the IDE's own tools build its structure - the program, then Party itself (created the moment it is first needed), then a new locale ... |
| Chapter 8: a text type, built | Step 1: The program, hard-coding English | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Show is the program's name - no application, no parameters, nothing injected. Type Show and choose Preview. The EK9 IDE just before choosing Preview: Show is the program's name - no ... |
| Chapter 8: a text type, built | Step 2: announce - the real message | Select the hard-coded greeting, right-click it and choose Localisation ▸ Extract to Localized Text…. Name the method announce; type Party as the text type - new, so the dialog offers where to create it (this file, already filled in) and its first locale (en); name party as the text variable - not ... |
| Chapter 8: a text type, built | Step 3: Adding French | Choose Code > Localisation > Add Locale… The EK9 IDE once this is done: Choose Code > Localisation > Add Locale… Adding French, cloned from en - a stub, //AI: translate the message, waits where the real words go. Type fr as the new locale - en is already chosen to clone from, the only locale so ... |
| Chapter 8: a text type, built | Step 4: Adding German | Choose Code > Localisation > Add Locale… The EK9 IDE once this is done: Choose Code > Localisation > Add Locale… Adding German, cloned from en the same way. Type de as the new locale - en is already chosen to clone from, the only locale so far. Choose Preview. The EK9 IDE just before choosing ... |
| Chapter 8: a text type, built | Step 5: Every language | Three languages now exist; Show still only ever greets in English. Replace party <- Party("en") with a loop over all three, and re-indent the println inside it. The EK9 IDE once this is done: Three languages now exist; Show still only ever greets in English |
| Chapter 8: a text type, built | Step 6: Run it | Choose Run > Run Program… The EK9 IDE once this is done: Choose Run > Run Program… The project's only program is already chosen. Choose Run. Sam's birthday is announced three times, once per language. Choose Close. The EK9 IDE just before choosing Close: Sam's birthday is announced three times, ... |
| Chapter 8: a text type, built | The result | Birthday.ek9 now reads exactly as chapter 8 of Getting Started with EK9 shows it: a text type the tools built - including the new Party type and party's own declaration, both from one Extract to Localized Text call - with each locale's wording typed by hand, the one thing no tool can write. ... |
| Chapter 8: a text type, built | Where this lesson comes from | For AI assistants - the MCP tool ek9_add_program, ek9_extract_to_localized_text, ek9_edit_localized_text. |
| Chapter 9: collections, asked about | Chapter 9: collections, asked about | Chapter 9 meets EK9's two core collections: the List, an ordered sequence, and the Dict, a set of key to value pairs. Basket shops from a List against a Dict of prices - getOrDefault's own unset Money() tells a missing price apart from a free one, so the total stays honest and what is not stocked ... |
| Chapter 9: collections, asked about | Step 1: The program | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Basket is the program's name - no application to bind, no parameters, nothing injected. Type Basket and choose Preview. The EK9 IDE just before choosing Preview: Basket is the program's ... |
| Chapter 9: collections, asked about | Step 2: Ask: /q 129 | Type /q 129 into the input bar above the editor and choose -> to send it - a direct lookup, by the question's own number, into the Answers tab. The EK9 IDE once this is done: Type /q 129 into the input bar above the editor and choose -> to send it - a direct lookup, by the question's own number, ... |
| Chapter 9: collections, asked about | Step 3: Read Effective API: List | Select basket, on the line that declares it, then choose Analyse ▸ Effective API: cursor-anchored, the same way chapter 7 read a Dimension and chapter 11 read a Result before them. The EK9 IDE once this is done: Select basket, on the line that declares it, then choose Analyse ▸ Effective API The ... |
| Chapter 9: collections, asked about | Step 4: Read Effective API: Dict | Select prices, on the line that declares it, then choose Analyse ▸ Effective API again - the same pane, a different type. The EK9 IDE once this is done: Select prices, on the line that declares it, then choose Analyse ▸ Effective API again - the same pane, a different type Dict of (String, ... |
| Chapter 9: collections, asked about | Step 5: Run it | Choose Run > Run Program… The EK9 IDE once this is done: Choose Run > Run Program… The project's only program is already chosen. Choose Run. Apples: £0.35, Bread: £1.10 and Milk: £0.85, Total: £2.30 - then Not available: ["Kiwi", "Mango"], the two the shop does not stock. Choose Close. The EK9 ... |
| Chapter 9: collections, asked about | The result | Basket.ek9 now reads exactly as chapter 9 of Getting Started with EK9 shows it: prices looked up with getOrDefault's own unset Money() default, so what the shop does not stock is told apart from what costs nothing. /q 129 then answered the same getOrDefault question from the Q&A corpus, and ... |
| Chapter 9: collections, asked about | Where this lesson comes from | Answers - ek9 -q and the IDE's Answers tab: 129.For AI assistants - the MCP tool ek9_add_program, ek9_ask, ek9_query_effective_api. |
| Chapter 20: a generic type, read | Chapter 20: a generic type, read | Chapter 20 names something you have been using since Collections without the word: List of String, Dict of (String, Integer), Optional and Result are all GENERIC - one definition with a gap, filled in when you use it. Show builds a List of String and a List of Integer side by side, then a Dict ... |
| Chapter 20: a generic type, read | Step 1: The program | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Show is the program's name - no application to bind, no parameters, nothing injected. Type Show and choose Preview. The EK9 IDE just before choosing Preview: Show is the program's name - ... |
| Chapter 20: a generic type, read | Step 2: Read names's Type Hierarchy | Select names, on the line that declares it, then choose Analyse ▸ Type Hierarchy: cursor-anchored, the same way Effective API reads the type under the caret. The EK9 IDE once this is done: Select names, on the line that declares it, then choose Analyse ▸ Type Hierarchy The pane draws two boxes: ... |
| Chapter 20: a generic type, read | Step 3: Read primes's Effective API | Select primes, on the line that declares it, then choose Analyse ▸ Effective API: the SAME pane Divide's Result read in chapter 11. The EK9 IDE once this is done: Select primes, on the line that declares it, then choose Analyse ▸ Effective API Above the sections, extends Any reads the same line ... |
| Chapter 20: a generic type, read | Step 4: Run it | Choose Run > Run Program… The EK9 IDE once this is done: Choose Run > Run Program… The project's only program is already chosen. Choose Run. names (List of String): ["Ada", "Alan"], then primes (List of Integer): [2, 3], then Ada scored 90 - the Dict literal read back by its own key. Choose ... |
| Chapter 20: a generic type, read | The result | Generics.ek9 now reads exactly as chapter 20 of Getting Started with EK9 shows it: one List, filled with String then with Integer, and a Dict literal alongside it - the same generic family you have used since Collections, named. Analyse ▸ Type Hierarchy then read List of String's own place in the ... |
| Chapter 20: a generic type, read | Where this lesson comes from | For AI assistants - the MCP tool ek9_new_construct, ek9_add_program, ek9_query_type_hierarchy, ek9_query_effective_api. |
| Chapter 22: a program with arguments, built | Chapter 22: a program with arguments, built | Chapter 22 closes with a setting that cannot live in the code at all: a web address. NoteLink takes one typed argument, a note's number, and builds a link to it on a server named by the NOTES_SERVER environment variable - never written into the source. The IDE's own tools make the program's whole ... |
| Chapter 22: a program with arguments, built | Step 1: NoteLink — the program | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… NoteLink is the program's name. Add one CLI parameter, noteNumber of type Integer - EK9 parses the text on the command line into it. Choose Preview. The EK9 IDE just before choosing ... |
| Chapter 22: a program with arguments, built | Step 2: Run it, with an argument | Choose Run > Run Program… The EK9 IDE once this is done: Choose Run > Run Program… Type 7 into Arguments (space-separated), then choose Run. The EK9 IDE just before choosing Run: Type 7 into Arguments (space-separated), then choose Run NOTES_SERVER is not set to a web address - nothing has given ... |
| Chapter 22: a program with arguments, built | Step 3: Run it again, from a saved configuration | Choose Run > Configurations… The EK9 IDE once this is done: Choose Run > Configurations… Choose + New Configuration… - NoteLink is already the program it will belong to. Name it With server, type 7 into Arguments, and into Environment type NOTES_SERVER=https://notes.example.com - the one field ... |
| Chapter 22: a program with arguments, built | The result | NoteLink.ek9 now reads exactly as chapter 22 of Getting Started with EK9 shows it: one program, one typed parameter, and a URL read from an environment variable rather than written into the code. Running it with just the argument shows NOTES_SERVER is not set; saving a run configuration through ... |
| Chapter 22: a program with arguments, built | Where this lesson comes from | For AI assistants - the MCP tool ek9_add_program, ek9_run_program. |
| Chapter 23: the game, built and played | Chapter 23: the game, built and played | Chapter 23 is the whole book in one program: a number-guessing game, built from a record, a class, six small functions and a thin program that ties them to the keyboard - the biggest example in the book. The IDE's own tools make the structure - every field's declaration, every constructor's and ... |
| Chapter 23: the game, built and played | Step 1: Score — a record, with its fields | Choose Code > New Construct > Record… The EK9 IDE once this is done: Choose Code > New Construct > Record… Score is the record's name. Add who (String) and attempts (Integer), each given a starting Value - String()/Integer(), a freshly made but unset value - so the record needs no constructor of ... |
| Chapter 23: the game, built and played | Step 2: Building a Score, blank then complete | Right-click the Score line and choose Add Constructor > No-Arg (default, pure) - a blank Score to fall back on. The EK9 IDE once this is done: Right-click the Score line and choose Add Constructor > No-Arg (default, pure) - a blank Score to fall back on Right-click the Score line again and choose ... |
| Chapter 23: the game, built and played | Step 3: Score's own operators | Right-click the Score line and choose Add Operator > $ (string) > skeleton. The EK9 IDE once this is done: Right-click the Score line and choose Add Operator > $ (string) > skeleton Select the stub line and type $'s own text form - the name, then the tries in parentheses. Saves when typed. The ... |
| Chapter 23: the game, built and played | Step 4: Game — a class, with its first fields | Choose Code > New Construct > Class… The EK9 IDE once this is done: Choose Code > New Construct > Class… Game is the class's name. Closed is already selected - EK9's default. Type Game and choose Preview. The EK9 IDE just before choosing Preview: Game is the class's name The preview shows Game ... |
| Chapter 23: the game, built and played | Step 5: Building a Game, blank then complete | Right-click the Game line and choose Add Constructor > Private No-Arg (default, pure) - private, so nothing outside the class can build a half-made game. The EK9 IDE once this is done: Right-click the Game line and choose Add Constructor > Private No-Arg (default, pure) - private, so nothing ... |
| Chapter 23: the game, built and played | Step 6: guess — taking one guess | Right-click the Game line and choose Add Method… The EK9 IDE once this is done: Right-click the Game line and choose Add Method… guess is the method's name - one parameter, number as Integer, returning String; not pure, since it changes tries and solved. Add the parameter, fill the rest in, and ... |
| Chapter 23: the game, built and played | Step 7: over, triesUsed and report | Right-click the Game line and choose Add Method… The EK9 IDE once this is done: Right-click the Game line and choose Add Method… over is the name, Boolean the return type, pure ticked - over only reads the game's state. Fill it in and choose Apply. The EK9 IDE just before choosing Apply: over is ... |
| Chapter 23: the game, built and played | Step 8: hint and rank — two pure functions | Choose Code > New Construct > Function… The EK9 IDE once this is done: Choose Code > New Construct > Function… hint is the function's name. Add two parameters, secret and guess, both Integer, set Returns to String, and tick pure. Choose Preview. The EK9 IDE just before choosing Preview: hint is ... |
| Chapter 23: the game, built and played | Step 9: The board helpers | Choose Code > New Construct > Function… The EK9 IDE once this is done: Choose Code > New Construct > Function… startingBoard is the name - no parameters, not pure. Set Returns to List of Score and choose Preview. The EK9 IDE just before choosing Preview: startingBoard is the name - no parameters, ... |
| Chapter 23: the game, built and played | Step 10: playerName — reading the command line | Choose Code > New Construct > Function… The EK9 IDE once this is done: Choose Code > New Construct > Function… playerName is the name - one parameter, argv as List of String, not pure. Set Returns to String and choose Preview. The EK9 IDE just before choosing Preview: playerName is the name - one ... |
| Chapter 23: the game, built and played | Step 11: The program — a thin shell | Choose Code > New Construct > Program… The EK9 IDE once this is done: Choose Code > New Construct > Program… Guess is the program's name - one CLI parameter, argv as List of String, in the SAME dialog's own CLI parameters table. Add it, type Guess, and choose Preview. The EK9 IDE just before ... |
| Chapter 23: the game, built and played | Step 12: Playing it, through the debugger | Click the debug (bug) icon beside the Guess() line - no saved configuration exists for it yet. The EK9 IDE once this is done: Click the debug (bug) icon beside the Guess() line - no saved configuration exists for it yet Choose + New Configuration… - this run needs a fixed seed, which only a saved ... |
| Chapter 23: the game, built and played | The result | Guess.ek9 now builds, compiles and plays exactly as chapter 23 describes it: a Score record, a Game class, six small functions and the program that connects them to Stdin, OS().random and GetOpt - built by the tools, logic you typed - then played for real, through the debugger: a win in four ... |
| Chapter 23: the game, built and played | Where this lesson comes from | For AI assistants - the MCP tool ek9_new_construct, ek9_add_field, ek9_add_constructor, ek9_add_method, ek9_add_operator, ek9_add_program, ek9_debug_session. |
| Chapter 23: running the tests, and the Journal | Chapter 23: running the tests, and the Journal | Chapter 23 ends two ways: fifteen tests that cover the record, the class and the functions, and a game you can actually play. This lesson plays the first ending, and then looks inside the class those tests already exercised, through the Journal. To play it in the IDE: Help > Lessons > Writing ... |
| Chapter 23: running the tests, and the Journal | Step 1: Running the tests | Run ▸ Run Tests (⌘T) runs every @Test in the project - all fifteen of them - and reports pass or fail, the same as ek9 -t at the command line. Choose Run Tests. The EK9 IDE once this is done: Run ▸ Run Tests (⌘T) runs every @Test in the project - all fifteen of them - and reports pass or fail, ... |
| Chapter 23: running the tests, and the Journal | Step 2: The Journal | Choose Run > New Journal Investigation… The EK9 IDE once this is done: Choose Run > New Journal Investigation… The project has several programs - Guess, and every @Test. Choose WinningGame, watch Game.tries, and leave the input sets blank: WinningGame takes no arguments, so one line is one run ... |
| Chapter 23: running the tests, and the Journal | The result | All fifteen tests pass, covering everything but the interactive loop - and the Journal showed exactly what WinningGame's own asserts already proved: tries counted up, one for each guess, inside a class that was tested long before the program that uses it ever ran. |
| Chapter 23: running the tests, and the Journal | Where this lesson comes from | For AI assistants - the MCP tool ek9_run_tests, ek9_debug_inspect. |
| Extract Constant | Extract Constant | Extract Constant gives a literal a name: a constant defined once, and every use of the literal in the file replaced by it. Here 18 in a comparison says nothing about what it means, so EK9 refuses it - E11064, explained in the Hovers panel; a literal used three times or more is refused the same ... |
| Extract Constant | Step 1: Where it is | Put the caret on 18, on line 8. The EK9 IDE once this is done: Put the caret on 18, on line 8 |
| Extract Constant | Step 2: Extract Constant | Right-click it - or choose Refactor > Refactor This… - and choose Extract Constant… The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Extract Constant… Name it ADULT_AGE - what 18 stands for - and choose Preview. The EK9 IDE just before choosing ... |
| Extract Constant | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. The EK9 IDE just before choosing Apply: The preview shows every change the refactoring makes; then the IDE formats each file it changed |
| Extract Constant | The result | That is Extract Constant: 18 is ADULT_AGE, defined once in a defines constant block, every use in the file replaced - also the fix for E11065, a literal used three times or more. It is on the right-click menu wherever the caret is on a literal; AI assistants use the ek9_extract_constant tool. The ... |
| Extract Constant | Where this lesson comes from | The errors it fixes - each one's explanation offers this lesson: E11064, E11065.Answers - ek9 -q and the IDE's Answers tab: 317, 638, 1184.For AI assistants - the MCP tool ek9_extract_constant. |
| Rename Symbol | Rename Symbol | Rename Symbol renames a name and every use of it, wherever it is. Here temp says nothing of what it holds, so EK9 refuses it - E11031, explained in the Hovers panel - as it refuses flag, data, value and the others below it. To play it in the IDE: Help > Lessons > Refactoring…, or ek9 -ide -lesson ... |
| Rename Symbol | Step 1: Where it is | Put the caret on temp, on line 8. The EK9 IDE once this is done: Put the caret on temp, on line 8 |
| Rename Symbol | Step 2: Rename Symbol | Choose Refactor > Rename Symbol… The EK9 IDE once this is done: Choose Refactor > Rename Symbol… Type the new name, mainText - what it holds - and choose Preview. The EK9 IDE just before choosing Preview: Type the new name, mainText - what it holds - and choose Preview |
| Rename Symbol | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. The EK9 IDE just before choosing Apply: The preview shows every change the refactoring makes; then the IDE formats each file it changed |
| Rename Symbol | The result | That is Rename Symbol: temp is mainText, at its declaration and its use. The seven names below it are the same refactoring - try one yourself. Shift+F6 opens it; AI assistants use the ek9_rename_symbol tool. The EK9 IDE when the lesson has finished |
| Rename Symbol | Where this lesson comes from | The errors it fixes - each one's explanation offers this lesson: E11031, E11030, E11032.Answers - ek9 -q and the IDE's Answers tab: 291, 297, 922, 1037.For AI assistants - the MCP tool ek9_rename_symbol. |
| Extract Variable | Extract Variable | Extract Variable gives part of an expression a name: a local that holds it, and the expression using the name. Here one expression does too much at once to read, so EK9 refuses it - E11013, explained in the Hovers panel. To play it in the IDE: Help > Lessons > Refactoring…, or ek9 -ide -lesson ... |
| Extract Variable | Step 1: The expression | Select (first ?: second) <? third, on line 12. The EK9 IDE once this is done: Select (first ?: second) <? third, on line 12 |
| Extract Variable | Step 2: Extract Variable | Choose Refactor > Extract Variable… The EK9 IDE once this is done: Choose Refactor > Extract Variable… Name it lower - the lower of the first two and the third - and choose Preview. The EK9 IDE just before choosing Preview: Name it lower - the lower of the first two and the third - and choose ... |
| Extract Variable | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. The EK9 IDE just before choosing Apply: The preview shows every change the refactoring makes; then the IDE formats each file it changed |
| Extract Variable | The result | That is Extract Variable: (first ?: second) <? third is lower, and the expression that did too much reads lower >? fourth - the return's value moved into the body to make room for the local. AI assistants use the ek9_extract_variable tool. The EK9 IDE when the lesson has finished |
| Extract Variable | Where this lesson comes from | The errors it fixes - each one's explanation offers this lesson: E11013, E11069, E11070.Answers - ek9 -q and the IDE's Answers tab: 1302, 1393.For AI assistants - the MCP tool ek9_extract_variable. |
| Change Signature | Change Signature | Change Signature changes a function's parameters - adds, removes or reorders them - and every call to it with them. Here unusedOneOfTwo never uses notUsed, so EK9 refuses it (E08091, explained in the Hovers panel); removing it must take its argument out of the call in describeReady too. To play ... |
| Change Signature | Step 1: Where it is | Put the caret on unusedOneOfTwo, on line 11. The EK9 IDE once this is done: Put the caret on unusedOneOfTwo, on line 11 |
| Change Signature | Step 2: Change Signature | Choose Refactor > Change Signature… The EK9 IDE once this is done: Choose Refactor > Change Signature… Choose notUsed in the parameters, then Remove, then Preview. The EK9 IDE just before choosing Preview: Choose notUsed in the parameters, then Remove, then Preview |
| Change Signature | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. The EK9 IDE just before choosing Apply: The preview shows every change the refactoring makes; then the IDE formats each file it changed |
| Change Signature | The result | That is Change Signature: notUsed is gone from unusedOneOfTwo, and its argument from the call in describeReady. The error left - ignored, in unusedSingleParam - is the same refactoring: try it yourself (nothing calls it, so only its declaration changes). Cmd+F6 opens it (Ctrl+F6 elsewhere); AI ... |
| Change Signature | Where this lesson comes from | The errors it fixes - each one's explanation offers this lesson: E08091.Answers - ek9 -q and the IDE's Answers tab: 319.For AI assistants - the MCP tool ek9_change_signature. |
| Extract Method | Extract Method | Extract Method moves a block of statements into a function of its own, called where the block was. Here seven ifs inside each other are too deep to follow, so EK9 refuses it - E11011, explained in the Hovers panel; moving the inner four into a function of their own brings both under the limit. To ... |
| Extract Method | Step 1: The statements | Select from if mainValue > LEVEL_THREE, on line 19, to the end of the line with stdout.println, line 23. The EK9 IDE once this is done: Select from if mainValue > LEVEL_THREE, on line 19, to the end of the line with stdout.println, line 23 |
| Extract Method | Step 2: Extract Method | Choose Refactor > Extract Method… The EK9 IDE once this is done: Choose Refactor > Extract Method… Name it reportHighLevels - what the block does - and choose Preview. The EK9 IDE just before choosing Preview: Name it reportHighLevels - what the block does - and choose Preview |
| Extract Method | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. The EK9 IDE just before choosing Apply: The preview shows every change the refactoring makes; then the IDE formats each file it changed |
| Extract Method | The result | That is Extract Method: the inner four ifs are reportHighLevels, called where they were, with mainValue and stdout passed in - seven levels became three here and four there. Cmd+Option+M opens it (Ctrl+Alt+M elsewhere); AI assistants use the ek9_extract_method tool. The EK9 IDE when the lesson ... |
| Extract Method | Where this lesson comes from | The errors it fixes - each one's explanation offers this lesson: E11011, E11012, E11021, E11010.Answers - ek9 -q and the IDE's Answers tab: 814, 1020.For AI assistants - the MCP tool ek9_extract_method. |
| Safe Delete | Safe Delete | Safe Delete removes a class, a function, a method or a field once it has checked that nothing uses it. Here Derived's doWork repeats Base's word for word, so EK9 refuses it - E11044, explained in the Hovers panel; Derived has doWork from Base without it. To play it in the IDE: Help > Lessons > ... |
| Safe Delete | Step 1: Where it is | Put the caret on doWork, on line 11. The EK9 IDE once this is done: Put the caret on doWork, on line 11 |
| Safe Delete | Step 2: Safe Delete | Choose Refactor > Safe Delete… The EK9 IDE once this is done: Choose Refactor > Safe Delete… |
| Safe Delete | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. |
| Safe Delete | The result | That is Safe Delete: Derived's doWork is gone, and Derived has Base's. Had anything still used what you deleted, the preview would have listed each place instead of offering Apply. It is on the right-click menu wherever the caret is on a declaration, and is Delete safely… on each entry of the ... |
| Safe Delete | Where this lesson comes from | The errors it fixes - each one's explanation offers this lesson: E11044.Answers - ek9 -q and the IDE's Answers tab: 801.For AI assistants - the MCP tool ek9_safe_delete. |
| Unused Code | Unused Code | The Unused Code window finds every callable the workspace never reaches, from any program, service or test. Here tidy.ek9 declares two functions: greeting, which the Greet program calls, and forgottenHelper, which nothing calls at all. To play it in the IDE: Help > Lessons > Refactoring…, or ek9 ... |
| Unused Code | Step 1: Open the window | Choose View > Tool Windows > Unused Code. The EK9 IDE once this is done: Choose View > Tool Windows > Unused Code |
| Unused Code | Step 2: The findings | forgottenHelper is listed under 🗑 Dead - reached by nothing, so it is safe to remove. greeting is not listed at all: the Greet program calls it, so it is live. |
| Unused Code | Step 3: Delete it safely | Right-click forgottenHelper and choose Delete safely… The EK9 IDE once this is done: Right-click forgottenHelper and choose Delete safely… |
| Unused Code | Step 4: Preview and apply | The preview shows forgottenHelper's declaration gone, with nothing else to change - nothing else used it. Choose Apply. |
| Unused Code | The result | That is the Unused Code window: forgottenHelper is gone - nothing called it, in production or test code - and greeting, which the program does call, was never listed at all. Delete safely… on a finding reaches the SAME preview as Safe Delete from a declaration's own right-click menu, so a finding ... |
| Unused Code | Where this lesson comes from | For AI assistants - the MCP tool ek9_find_unused_code, ek9_safe_delete. |
| Organize Constants | Organize Constants | Organize Constants gathers every constant of a module into one file, so its fixed values are found in one place. Here three files of one module each define constants of their own, so EK9 refuses it - E11066, explained in the Hovers panel; ten or more constants across two files are refused the ... |
| Organize Constants | Step 1: Where it is | Put the caret on MAX_RETRIES, on line 5. The EK9 IDE once this is done: Put the caret on MAX_RETRIES, on line 5 |
| Organize Constants | Step 2: Organize Constants | Choose Refactor > Organize Constants… The EK9 IDE once this is done: Choose Refactor > Organize Constants… Choose new file, name it constants.ek9 - a file of the module's own for its constants - and choose Preview. The EK9 IDE just before choosing Preview: Choose new file, name it constants.ek9 - ... |
| Organize Constants | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. The EK9 IDE just before choosing Apply: The preview shows every change the refactoring makes; then the IDE formats each file it changed |
| Organize Constants | The result | That is Organize Constants: the six constants are one block in constants.ek9, and the three files they came from hold only their module line - delete them, or keep them for what comes next. Which file a constant is in makes no difference to the code that uses it. AI assistants use the ... |
| Organize Constants | Where this lesson comes from | The errors it fixes - each one's explanation offers this lesson: E11066, E11067.Answers - ek9 -q and the IDE's Answers tab: 863, 1341.For AI assistants - the MCP tool ek9_organize_constants. |
| Organize References | Organize References | Organize References deletes the unused entries of one file's references block - usage judged by a scratch compile, so it is never fooled by a name collision. Here workshop.ek9 references both polish and sharpen from toolbox.ek9, but only ever calls sharpen. To play it in the IDE: Help > Lessons > ... |
| Organize References | Step 1: Where it is | Put the caret on polish, on line 5. The EK9 IDE once this is done: Put the caret on polish, on line 5 |
| Organize References | Step 2: Organize References | Right-click it - or choose Refactor > Refactor This… - and choose Organize References. The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Organize References |
| Organize References | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. |
| Organize References | The result | That is Organize References: polish is gone from the references block, and sharpen - the one it actually calls - is untouched. Which functions a file references makes no difference to how fast it runs; it is about the block reading true. It is on the Code menu and the right-click menu whenever ... |
| Organize References | Where this lesson comes from | For AI assistants - the MCP tool ek9_organize_references. |
| Sync References | Sync References | Sync References does what Organize References does - delete unused entries - and also adds the entry for any cross-module symbol the file uses but has not declared, in one pass. Here garden.ek9 references both prune and water from shed.ek9, but only ever calls water. To play it in the IDE: Help > ... |
| Sync References | Step 1: Where it is | Put the caret on prune, on line 5. The EK9 IDE once this is done: Put the caret on prune, on line 5 |
| Sync References | Step 2: Sync References | Right-click it - or choose Refactor > Refactor This… - and choose Sync References. The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Sync References |
| Sync References | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. |
| Sync References | The result | That is Sync References: prune is gone from the references block, and water is untouched - the same result Organize References gives here, because nothing was missing to add. On a file that calls a symbol it has not yet referenced, Sync adds the module::Name entry instead of leaving the error; ... |
| Sync References | Where this lesson comes from | For AI assistants - the MCP tool ek9_sync_references. |
| Inline Variable | Inline Variable | Inline Variable puts a local's value where the local is used, and removes the local - the reverse of Extract Variable. Here total is set once and read once, on the very next line: the name says nothing that price * quantity does not. To play it in the IDE: Help > Lessons > Refactoring…, or ek9 ... |
| Inline Variable | Step 1: Where it is | Put the caret on total, on line 12. The EK9 IDE once this is done: Put the caret on total, on line 12 |
| Inline Variable | Step 2: Inline Variable | Choose Refactor > Inline Variable. The EK9 IDE once this is done: Choose Refactor > Inline Variable |
| Inline Variable | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. |
| Inline Variable | The result | That is Inline Variable: total is gone, and rtn takes price * quantity itself. Where inlining would change what the code does - a local assigned again, or a call that would then run twice - the preview says so instead of offering Apply. Cmd+Option+N opens it (Ctrl+Alt+N elsewhere), the Inline ... |
| Inline Variable | Where this lesson comes from | For AI assistants - the MCP tool ek9_inline_variable. |
| Introduce Parameter | Introduce Parameter | Introduce Parameter turns a value a function uses into one its callers pass - and passes the old value at every call, so nothing changes until a caller wants something else. Here discounted always uses STANDARD_RATE; a caller that needs another rate cannot ask for one. To play it in the IDE: Help ... |
| Introduce Parameter | Step 1: The expression | Select STANDARD_RATE, on line 11. The EK9 IDE once this is done: Select STANDARD_RATE, on line 11 |
| Introduce Parameter | Step 2: Introduce Parameter | Choose Refactor > Introduce Parameter… The EK9 IDE once this is done: Choose Refactor > Introduce Parameter… Name it rate - what a caller now chooses - and choose Preview. The EK9 IDE just before choosing Preview: Name it rate - what a caller now chooses - and choose Preview |
| Introduce Parameter | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. The EK9 IDE just before choosing Apply: The preview shows every change the refactoring makes; then the IDE formats each file it changed |
| Introduce Parameter | The result | That is Introduce Parameter: discounted takes rate, and the call in Discounts passes STANDARD_RATE - what it used before, so the program prints the same. Another caller can now pass another rate. At four parameters or more the calls are given named arguments (E11062). Cmd+Option+P opens it ... |
| Introduce Parameter | Where this lesson comes from | For AI assistants - the MCP tool ek9_introduce_parameter. |
| Inline Function | Inline Function | Inline Function puts a function's body in place of every call to it, and removes the function - the reverse of Extract Method. Here welcome does nothing but call greeting: a name between the caller and the work that adds nothing. To play it in the IDE: Help > Lessons > Refactoring…, or ek9 -ide ... |
| Inline Function | Step 1: Where it is | Put the caret on welcome, on line 10. The EK9 IDE once this is done: Put the caret on welcome, on line 10 |
| Inline Function | Step 2: Inline Function | Choose Refactor > Inline Function… The EK9 IDE once this is done: Choose Refactor > Inline Function… |
| Inline Function | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. |
| Inline Function | The result | That is Inline Function: Greeter calls greeting itself, and welcome is gone. Where the function's own locals would clash with names at a call, the preview says which to rename first instead of offering Apply. Cmd+Option+I opens it (Ctrl+Alt+I elsewhere); AI assistants use the ek9_inline_function ... |
| Inline Function | Where this lesson comes from | For AI assistants - the MCP tool ek9_inline_function. |
| Move Construct | Move Construct | Move Construct moves a class, record, trait, component or function to another file - into that file's module, when it is another - and every reference to it follows. Here priceLabel is about money but sits in the shop's module, lesson.shop; money.ek9, in lesson.money, is where it belongs. To play ... |
| Move Construct | Step 1: Where it is | Put the caret on priceLabel, on line 9. The EK9 IDE once this is done: Put the caret on priceLabel, on line 9 |
| Move Construct | Step 2: Move Construct | Choose Refactor > Move Construct… The EK9 IDE once this is done: Choose Refactor > Move Construct… Move to file is money.ek9 - in lesson.money, so the move is cross-module. Choose Preview. |
| Move Construct | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. The EK9 IDE just before choosing Apply: The preview shows every change the refactoring makes; then the IDE formats each file it changed |
| Move Construct | The result | That is Move Construct: priceLabel now lives in money.ek9, in lesson.money, and shop.ek9 references it as lesson.money::priceLabel, beside withVat. A move within one module changes no reference at all. F6 opens it; AI assistants use the ek9_move_construct tool. The EK9 IDE when the lesson has ... |
| Move Construct | Where this lesson comes from | For AI assistants - the MCP tool ek9_move_construct. |
| Lift into Guard | Lift into Guard | Lift into Guard turns a declare-then-check pattern into one guarded head: a variable declared, then immediately tested with '?', becomes the control construct's own guard - entering only when the value is set, the separate check gone. Here greeting is declared, then checked with greeting? before ... |
| Lift into Guard | Step 1: Where it is | Put the caret on greeting?, on line 18. The EK9 IDE once this is done: Put the caret on greeting?, on line 18 |
| Lift into Guard | Step 2: Lift into Guard | Right-click it - or choose Refactor > Refactor This… - and choose Lift into Guard… The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Lift into Guard… |
| Lift into Guard | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. |
| Lift into Guard | The result | That is Lift into Guard: greeting <- findGreeting("Steve") and if greeting? become one line, if greeting <- findGreeting("Steve") - the redundant greeting? check subsumed into the guard. It folds switch, try, while, do and for heads the same way, keeping a loop's own condition or iteration as a ... |
| Lift into Guard | Where this lesson comes from | Answers - ek9 -q and the IDE's Answers tab: 971, 1146.For AI assistants - the MCP tool ek9_apply_guard_pattern. |
| Wrap with coalescing | Wrap with coalescing | Wrap with coalescing puts a selected expression on the left of one of EK9's coalescing operators, with what to fall back on on the right: ?: defaults an unset value, <? and >? return the lesser or greater of two operands - the set one when only one is. Here displayName takes name with no default ... |
| Wrap with coalescing | Step 1: The expression | Select name, on line 9. The EK9 IDE once this is done: Select name, on line 9 |
| Wrap with coalescing | Step 2: Wrap with coalescing | Right-click it - or choose Refactor > Refactor This… - and choose Wrap with coalescing… The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Wrap with coalescing… Choose ?: - elvis, a default when the left is unset - type "Anonymous" for the right ... |
| Wrap with coalescing | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. The EK9 IDE just before choosing Apply: The preview shows every change the refactoring makes; then the IDE formats each file it changed |
| Wrap with coalescing | The result | That is Wrap with coalescing: displayName is name ?: "Anonymous" - "Anonymous" only when name is unset, name itself otherwise. <? and >? wrap the same way, returning whichever operand is set, or the lesser/greater when both are. It is on the right-click menu whenever a single-line expression is ... |
| Wrap with coalescing | Where this lesson comes from | Answers - ek9 -q and the IDE's Answers tab: 243, 1059, 1067.For AI assistants - the MCP tool ek9_insert_coalescing. |
| Make Open | Make Open | Change Modifier > Make Open adds 'as open' to a closed class, record, component or function, so it can be extended. EK9 types are closed by default - the opposite of most languages - so Shape cannot be extended until it says so; EK9 refuses Circle's attempt to extend it - E05030, explained in the ... |
| Make Open | Step 1: Where it is | Put the caret on Shape, on line 6. The EK9 IDE once this is done: Put the caret on Shape, on line 6 |
| Make Open | Step 2: Make Open | Right-click it - or choose Refactor > Refactor This… - and choose Change Modifier > Make Open. The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Change Modifier > Make Open |
| Make Open | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. |
| Make Open | The result | That is Make Open: Shape now says 'as open', so Circle extends it cleanly. Make Closed, Make Abstract and Make Concrete sit beside it in the same right-click Change Modifier submenu - the opposite narrowings. AI assistants use the ek9_make_open tool. The EK9 IDE when the lesson has finished |
| Make Open | Where this lesson comes from | The errors it fixes - each one's explanation offers this lesson: E05030.Answers - ek9 -q and the IDE's Answers tab: 101, 102, 1043.For AI assistants - the MCP tool ek9_make_open. |
| Fix Purity Contract | Fix Purity Contract | Fix Purity Contract adds, or removes, 'as pure' on the callable a purity error names - with the override cascade applied automatically. EK9 purity is about mutation and non-pure calls, not input or output: stdout.println is itself declared pure, so printing is always allowed inside a pure method; ... |
| Fix Purity Contract | Step 1: Where the error is | Put the caret on WordLength, on line 10 - the override the compiler flagged. The EK9 IDE once this is done: Put the caret on WordLength, on line 10 - the override the compiler flagged |
| Fix Purity Contract | Step 2: Blast Radius: the fix it offers | Choose Analyse > Blast Radius. It draws Measure, the contract, in gold, and WordLength under it as fixable, and states the one fix there is - add pure to WordLength - with an Apply button beside it. Press that Apply. The EK9 IDE just before choosing 🔧 Apply — Add pure to WordLength(): Choose ... |
| Fix Purity Contract | Step 3: Preview and apply | The preview shows WordLength gaining 'as pure'; then the IDE formats the file. Choose Apply. The EK9 IDE just before choosing Apply: The preview shows WordLength gaining 'as pure'; then the IDE formats the file |
| Fix Purity Contract | The result | That is Fix Purity Contract: WordLength is now 'as pure', matching what Measure promises. The same picture - the Blast Radius pane draws - is what ek9_query_purity_impact answers read-only; AI assistants call ek9_fix_purity_contract directly, with the diagnostic's file, line and mode. The EK9 IDE ... |
| Fix Purity Contract | Where this lesson comes from | The errors it fixes - each one's explanation offers this lesson: E05150, E05160, E08130.Answers - ek9 -q and the IDE's Answers tab: 560, 561, 562.For AI assistants - the MCP tool ek9_fix_purity_contract. |
| Implement Methods | Implement Methods | Implement Methods adds an override stub for every abstract trait method a class has not yet implemented. Here C6 declares trait T1, which requires tMethod() and operator +; C6 has overridden the operator but not tMethod(), so EK9 refuses it - E07130, explained in the Hovers panel. To play it in ... |
| Implement Methods | Step 1: Where it is | Put the caret on C6, on line 65. The EK9 IDE once this is done: Put the caret on C6, on line 65 |
| Implement Methods | Step 2: Implement Methods | Right-click it - or choose Refactor > Refactor This… - and choose Implement Methods… The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Implement Methods… |
| Implement Methods | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. |
| Implement Methods | The result | That is Implement Methods: C6 now has an override stub for tMethod(), so every obligation trait T1 asks of it is met. C5, C7, C8 and C9 are left - this tool batches a trait's METHODS only, so an outstanding operator (Add Operator) or an abstract method inherited from a superclass needs a ... |
| Implement Methods | Where this lesson comes from | The errors it fixes - each one's explanation offers this lesson: E07130.Answers - ek9 -q and the IDE's Answers tab: 103, 108.For AI assistants - the MCP tool ek9_implement_methods. |
| Rewrite String Concatenation | Rewrite String Concatenation | Rewrite String Concatenation turns a + chain of three or more parts into the equivalent backtick interpolation. Here "Hello " + name + "!" is three parts, so EK9 refuses it - E11068, explained in the Hovers panel. To play it in the IDE: Help > Lessons > Refactoring…, or ek9 -ide -lesson ... |
| Rewrite String Concatenation | Step 1: Where it is | Put the caret on Hello, on line 9. The EK9 IDE once this is done: Put the caret on Hello, on line 9 |
| Rewrite String Concatenation | Step 2: Rewrite String Concatenation | Right-click it - or choose Refactor > Refactor This… - and choose Localisation > Rewrite to Backtick Interpolation. The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Localisation > Rewrite to Backtick Interpolation |
| Rewrite String Concatenation | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. |
| Rewrite String Concatenation | The result | That is Rewrite String Concatenation: "Hello " + name + "!" is Hello ${name}!, one allocation instead of three. The four- and five-part chains below it are the same refactoring - try one yourself. It is on the right-click menu wherever the caret is inside a + concatenation; AI assistants use the ... |
| Rewrite String Concatenation | Where this lesson comes from | The errors it fixes - each one's explanation offers this lesson: E11068.Answers - ek9 -q and the IDE's Answers tab: 309, 174, 313.For AI assistants - the MCP tool ek9_rewrite_string_concat. |
| Pull Up | Pull Up | Pull Up promotes a method or operator from a subclass into its superclass, where every subclass can use it - with no dialog: the superclass comes from the subclass's 'extends' clause. Here describe() is declared on Circle, but has nothing to do with being a circle - Square, right beside it, could ... |
| Pull Up | Step 1: Where it is | Put the caret on describe, on line 10. The EK9 IDE once this is done: Put the caret on describe, on line 10 |
| Pull Up | Step 2: Pull Up | Right-click it - or choose Refactor > Refactor This… - and choose Pull 'describe' Up to Shape… The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Pull 'describe' Up to Shape… |
| Pull Up | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. |
| Pull Up | The result | That is Pull Up: describe() is gone from Circle and lives on Shape itself, so Square could call it too. A member that uses state only the subclass has, or a name already on the superclass, surfaces in the preview instead of a silent wrong move. It is on the right-click menu wherever the caret is ... |
| Pull Up | Where this lesson comes from | For AI assistants - the MCP tool ek9_pull_up. |
| Push Down | Push Down | Push Down relocates a method or operator from a superclass into the subclasses you choose: removed from the superclass, copied into each one picked. Here fly() is declared on Bird, but a Penguin cannot fly - only Eagle should keep it. To play it in the IDE: Help > Lessons > Refactoring…, or ek9 ... |
| Push Down | Step 1: Where it is | Put the caret on fly, on line 8. The EK9 IDE once this is done: Put the caret on fly, on line 8 |
| Push Down | Step 2: Push Down | Right-click it - or choose Refactor > Refactor This… - and choose Push 'fly' Down… The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Push 'fly' Down… Tick Eagle only - Penguin stays without fly() - and choose Preview. The EK9 IDE just before choosing ... |
| Push Down | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. The EK9 IDE just before choosing Apply: The preview shows every change the refactoring makes; then the IDE formats each file it changed |
| Push Down | The result | That is Push Down: fly() is gone from Bird and lives on Eagle alone; Penguin has none at all. A caller that reached the member through the superclass type, or a subclass left out that still needed it, surfaces in the preview instead of a silent wrong move. It is on the right-click menu wherever ... |
| Push Down | Where this lesson comes from | For AI assistants - the MCP tool ek9_push_down. |
| Extract Trait | Extract Trait | Extract Trait pulls a class's public methods out into a NEW trait it then implements: the class keeps its bodies, gains 'with trait of' and the new trait's name on its header and 'override' on each extracted method. Here Product's describe() is the kind of thing other things in a catalogue could ... |
| Extract Trait | Step 1: Where it is | Put the caret on Product, on line 6. The EK9 IDE once this is done: Put the caret on Product, on line 6 |
| Extract Trait | Step 2: Extract Trait | Right-click it - or choose Refactor > Refactor This… - and choose Extract Trait… The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Extract Trait… Name it Describable - what describe() promises - and choose Preview. The EK9 IDE just before choosing ... |
| Extract Trait | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. The EK9 IDE just before choosing Apply: The preview shows every change the refactoring makes; then the IDE formats each file it changed |
| Extract Trait | The result | That is Extract Trait: Product now implements Describable, describe() is overridden, and the trait declares describe() as abstract for anything else that adopts it. A name already used in the file, or a method that is private, protected or an operator, surfaces as a conflict instead of an error ... |
| Extract Trait | Where this lesson comes from | For AI assistants - the MCP tool ek9_extract_trait. |
| Adopt Trait | Adopt Trait | Adopt Trait adds 'with trait of' and a trait's name to a class or component's declaration and, implementing, an override stub for every one of the trait's abstract methods - or, delegating, forwards them all to an existing field instead. Here Greeter declares one abstract method, greet(); Robot ... |
| Adopt Trait | Step 1: Right-click Robot | Right-click the Robot line and choose Adopt Trait… The EK9 IDE once this is done: Right-click the Robot line and choose Adopt Trait… |
| Adopt Trait | Step 2: Name the trait, and OK | Greeter is the trait - Implement method stubs is already chosen, the other way being to delegate to a field. Type Greeter and choose OK. The EK9 IDE just before choosing OK: Greeter is the trait - Implement method stubs is already chosen, the other way being to delegate to a field Adopt Trait ... |
| Adopt Trait | The result | That is Adopt Trait: Robot now says 'with trait of Greeter', and carries an override stub for greet() - the trait's one abstract method - with a //AI: Implement greet lead where the body goes. Delegate to a field instead and the compiler forwards every trait method for you, with no stub to fill ... |
| Adopt Trait | Where this lesson comes from | Answers - ek9 -q and the IDE's Answers tab: 108, 210.For AI assistants - the MCP tool ek9_adopt_trait. |
| Make Abstract | Make Abstract | Change Modifier > Make Abstract adds 'as abstract' to a class, record, component or function directly - an alternative to implementing every outstanding member. Here C7 extends C1, which is abstract, but implements neither of C1's abstract members, so EK9 refuses it - E07130, explained in the ... |
| Make Abstract | Step 1: Where it is | Put the caret on C7, on line 73. The EK9 IDE once this is done: Put the caret on C7, on line 73 |
| Make Abstract | Step 2: Make Abstract | Right-click it - or choose Refactor > Refactor This… - and choose Change Modifier > Make Abstract. The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Change Modifier > Make Abstract |
| Make Abstract | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. |
| Make Abstract | The result | That is Make Abstract: C7 now says 'as abstract', so it compiles without implementing C1's members itself - whatever extends C7 still owes them. C5, C8 and C9 are left, fixable the same way or by implementing the missing members (Implement Methods…, which fixes C6 the same error asks for); Make ... |
| Make Abstract | Where this lesson comes from | The errors it fixes - each one's explanation offers this lesson: E07130.Answers - ek9 -q and the IDE's Answers tab: 103.For AI assistants - the MCP tool ek9_make_abstract. |
| Make Closed | Make Closed | Change Modifier > Make Closed removes 'as open' from a class, record, component or function, returning it to EK9's closed-by-default. Here Shape says 'as open' but nothing extends it - an openness nobody uses. To play it in the IDE: Help > Lessons > Refactoring…, or ek9 -ide -lesson make-closed. ... |
| Make Closed | Step 1: Where it is | Put the caret on Shape, on line 6. The EK9 IDE once this is done: Put the caret on Shape, on line 6 |
| Make Closed | Step 2: Make Closed | Right-click it - or choose Refactor > Refactor This… - and choose Change Modifier > Make Closed. The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Change Modifier > Make Closed |
| Make Closed | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. |
| Make Closed | The result | That is Make Closed: Shape no longer says 'as open', so it is closed again - exactly where every EK9 type starts. Had anything already extended it, the preview would have listed each subtype instead of offering Apply. Make Open reverses it; Make Abstract and Make Concrete sit beside it in the ... |
| Make Closed | Where this lesson comes from | Answers - ek9 -q and the IDE's Answers tab: 574, 784.For AI assistants - the MCP tool ek9_make_closed. |
| Make Concrete | Make Concrete | Change Modifier > Make Concrete removes 'as abstract' from a class, record, component or function whose abstract members are all implemented, so it can be instantiated directly - keeping 'as open' unless told otherwise. Here Shape says 'as abstract' but has no abstract member at all: describe() ... |
| Make Concrete | Step 1: Where it is | Put the caret on Shape, on line 6. The EK9 IDE once this is done: Put the caret on Shape, on line 6 |
| Make Concrete | Step 2: Make Concrete | Right-click it - or choose Refactor > Refactor This… - and choose Change Modifier > Make Concrete. The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Change Modifier > Make Concrete |
| Make Concrete | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. |
| Make Concrete | The result | That is Make Concrete: Shape now says 'as open' instead of 'as abstract' - Circle still extends it, and Shape itself can now be constructed too. Had an abstract member remained, the preview would have listed it instead of offering Apply. Make Abstract reverses it; Make Open and Make Closed sit ... |
| Make Concrete | Where this lesson comes from | For AI assistants - the MCP tool ek9_make_concrete. |
| Seal Type | Seal Type | Change Modifier > Seal Type adds an 'allow only A, B, C' clause to a class or trait, restricting extension to exactly the subtypes listed - the compiler then knows the hierarchy is complete, so a switch over it can be exhaustive. Here Shape is open to anything; Circle and Square are its only two ... |
| Seal Type | Step 1: Where it is | Put the caret on Shape, on line 6. The EK9 IDE once this is done: Put the caret on Shape, on line 6 |
| Seal Type | Step 2: Seal Type | Right-click it - or choose Refactor > Refactor This… - and choose Change Modifier > Seal Type… The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Change Modifier > Seal Type… Circle and Square are already ticked - every existing subtype must stay ... |
| Seal Type | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. The EK9 IDE just before choosing Apply: The preview shows every change the refactoring makes; then the IDE formats each file it changed |
| Seal Type | The result | That is Seal Type: Shape now reads 'allow only Circle, Square as open' - only those two may extend it, and a third attempt is refused (E05240) until it is added to the list. Unseal Type removes the clause again; Add to Allowlist… adds one more name without starting over - both sit beside it in ... |
| Seal Type | Where this lesson comes from | Answers - ek9 -q and the IDE's Answers tab: 1171, 301, 608.For AI assistants - the MCP tool ek9_seal_type. |
| Unseal Type / Add to Allowlist | Unseal Type / Add to Allowlist | Add to Allowlist widens an existing 'allow only' list without starting over; Unseal Type removes the restriction entirely. Here SealedTrait's 'allow only AllowedClass1, AllowedClass2' refuses AddedLater and AlsoAddedLater - each its own E05240, explained in the Hovers panel - and a dynamic class, ... |
| Unseal Type / Add to Allowlist | Step 1: Add to Allowlist | Right-click the AddedLater line and choose Add to 'SealedTrait' allow only list… The EK9 IDE once this is done: Right-click the AddedLater line and choose Add to 'SealedTrait' allow only list… AddedLater and AlsoAddedLater are already ticked - every unlisted subtype of SealedTrait, so one edit ... |
| Unseal Type / Add to Allowlist | Step 2: Preview and apply | The preview shows both names added to SealedTrait's allow only list; then the IDE formats the file. Choose Apply. The EK9 IDE just before choosing Apply: The preview shows both names added to SealedTrait's allow only list; then the IDE formats the file |
| Unseal Type / Add to Allowlist | Step 3: Unseal Type | Right-click the SealedTrait line and choose Change Modifier > Unseal Type The EK9 IDE once this is done: Right-click the SealedTrait line and choose Change Modifier > Unseal Type |
| Unseal Type / Add to Allowlist | Step 4: Preview and apply | The preview shows the allow only clause removed entirely; then the IDE formats the file. Choose Apply. |
| Unseal Type / Add to Allowlist | The result | That is Add to Allowlist and Unseal Type: AddedLater and AlsoAddedLater are both in SealedTrait's allow only list - one edit admitted both, since each was its own E05240 - and the dynamic class's error, which no allowlist edit could ever fix, is gone only once SealedTrait is unsealed entirely. ... |
| Unseal Type / Add to Allowlist | Where this lesson comes from | The errors it fixes - each one's explanation offers this lesson: E05240.Answers - ek9 -q and the IDE's Answers tab: 301, 608, 303.For AI assistants - the MCP tool ek9_add_to_sealed_allowlist, ek9_unseal_type. |
| Introduce Field | Introduce Field | Introduce Field lifts a local and its initialiser up to a field of the enclosing class, record or component, keeping the same name - the field-level sibling of Introduce Parameter: Introduce Parameter turns a value a function uses into one its CALLERS pass; Introduce Field turns a value a METHOD ... |
| Introduce Field | Step 1: Where it is | Put the caret on balance, on line 7. The EK9 IDE once this is done: Put the caret on balance, on line 7 |
| Introduce Field | Step 2: Introduce Field | Right-click it - or choose Refactor > Refactor This… - and choose Introduce Field… The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Introduce Field… |
| Introduce Field | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. |
| Introduce Field | The result | That is Introduce Field: balance is now a field of Account, set once when the object is created and shared by every method after it - today just show(). Because this is Account's first field, the tool also appends default operator ? (EK9's tri-state requirement, E07235) so the result compiles in ... |
| Introduce Field | Where this lesson comes from | For AI assistants - the MCP tool ek9_introduce_field. |
| Rename Field | Rename Field | Rename Field renames a field and every reference to it inside its owning construct - the construct-scoped sibling of Rename Symbol, which reaches across the whole workspace. EK9 fields are private to their declaring construct, so a field's rename never needs to look beyond the one file that ... |
| Rename Field | Step 1: Where it is | Put the caret on farewell, on line 6. The EK9 IDE once this is done: Put the caret on farewell, on line 6 |
| Rename Field | Step 2: Rename Field | Right-click it - or choose Refactor > Refactor This… - and choose Rename Field… The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Rename Field… Name it signoff - the word the rest of the project uses for this - and choose Preview. The EK9 IDE just ... |
| Rename Field | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. The EK9 IDE just before choosing Apply: The preview shows every change the refactoring makes; then the IDE formats each file it changed |
| Rename Field | The result | That is Rename Field: farewell is signoff, at its declaration and every use inside Greeter - sayGoodbye included. Nothing outside Greeter needed to change, because nothing outside it could see farewell in the first place; a same-named constructor parameter, and its named arguments at every call, ... |
| Rename Field | Where this lesson comes from | For AI assistants - the MCP tool ek9_rename_field. |
| Remove Field | Remove Field | Remove Field deletes a field from a class, record or component once it has checked every reference inside that construct's body - the field-scoped sibling of Safe Delete, which reaches across the whole workspace. It classifies each reference it finds and offers a repair for the mechanical kinds, ... |
| Remove Field | Step 1: Where it is | Put the caret on spare, on line 7. The EK9 IDE once this is done: Put the caret on spare, on line 7 |
| Remove Field | Step 2: Remove Field | Right-click it - or choose Refactor > Refactor This… - and choose Remove Field… The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Remove Field… |
| Remove Field | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. |
| Remove Field | The result | That is Remove Field: spare is gone from Greeter, in one edit - name and the rest of the class unchanged. Had sayHello, or anywhere else inside Greeter, still read spare, the preview would have listed each reference, classified by kind, with a repair for the mechanical ones - a boolean-chain ... |
| Remove Field | Where this lesson comes from | For AI assistants - the MCP tool ek9_remove_field. |
| Change Visibility | Change Visibility | Change Visibility narrows or widens a method's access modifier - public, protected or private - and the submenu only ever offers the moves that are actually legal for the method under the caret. Here decorate is a helper describe alone calls; nothing outside Order uses it, so it can be private. ... |
| Change Visibility | Step 1: Where it is | Put the caret on decorate, on line 14. The EK9 IDE once this is done: Put the caret on decorate, on line 14 |
| Change Visibility | Step 2: Change Visibility | Right-click it - or choose Refactor > Refactor This… - and choose Change Visibility > Make Private. The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Change Visibility > Make Private |
| Change Visibility | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. |
| Change Visibility | The result | That is Change Visibility: decorate is private on Order - describe still calls it from inside the class, but nothing outside Order can. Make Public, Make Protected and Make Private sit together in the same submenu, and a narrowing that would strand an outside caller surfaces as a would-fail ... |
| Change Visibility | Where this lesson comes from | For AI assistants - the MCP tool ek9_change_visibility. |
| Surround With | Surround With | Surround With folds a selection of whole statements under an if, try/catch, for-range or while head - EK9 has no braces, so the tool re-indents the lines for you rather than leave it to be mis-typed by hand. Here warnLowStock always prints, even before stock is actually low. To play it in the ... |
| Surround With | Step 1: Surround it with if … | Put the caret on the stdout.println line, right-click it - or choose Refactor > Refactor This… - and choose Surround With ▸ if …. The EK9 IDE once this is done: Put the caret on the stdout.println line, right-click it - or choose Refactor > Refactor This… - and choose Surround With ▸ if … The ... |
| Surround With | The result | That is Surround With: warnLowStock's one statement is folded under 'if surroundGuard? //AI: Replace with condition' - an opaque placeholder you replace with the real stock check, the statement itself re-indented +2 spaces so EK9's brace-free layout is never mis-typed by hand. The same submenu ... |
| Surround With | Where this lesson comes from | For AI assistants - the MCP tool ek9_surround_with. |
| Generate Delegation | Generate Delegation | Generate Delegation wires a trait the class already declares to an existing field with 'by' and the field's name, so the compiler forwards every trait method to it - no bodies to write. Here Robot declares Greeter but has not yet delegated it, so greet() falls back to the trait's own default ... |
| Generate Delegation | Step 1: Where it is | Put the caret on Robot, on line 17. The EK9 IDE once this is done: Put the caret on Robot, on line 17 |
| Generate Delegation | Step 2: Generate Delegation | Right-click it - or choose Refactor > Refactor This… - and choose Generate Delegation… The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Generate Delegation… Greeter and inner are already chosen - Robot's only trait and only field. Choose Preview. |
| Generate Delegation | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. The EK9 IDE just before choosing Apply: The preview shows every change the refactoring makes; then the IDE formats each file it changed |
| Generate Delegation | The result | That is Generate Delegation: Robot now reads 'with trait of Greeter by inner', so greet() forwards to inner and returns 'Echo' instead of the trait's own 'Hello'. Wiring a trait the class does NOT yet declare is Adopt Trait's delegate mode instead; overriding one forwarded method yourself (Add ... |
| Generate Delegation | Where this lesson comes from | For AI assistants - the MCP tool ek9_generate_delegation. |
| Generate Dispatcher | Generate Dispatcher | Generate Dispatcher scaffolds a dispatcher entry - 'sound() as dispatcher', say - plus one handler overload per subtype of a base type - sealed for exhaustive dispatch, or open with the entry's own fallback covering the rest. Here Animal allows only Dog and Cat; AnimalDispatcher has no dispatcher ... |
| Generate Dispatcher | Step 1: Where it is | Put the caret on AnimalDispatcher, on line 12. The EK9 IDE once this is done: Put the caret on AnimalDispatcher, on line 12 |
| Generate Dispatcher | Step 2: Generate Dispatcher | Right-click it - or choose Refactor > Refactor This… - and choose Generate Dispatcher… The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Generate Dispatcher… Animal is already chosen - the workspace's one sealed type. Name the dispatcher sound and ... |
| Generate Dispatcher | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. The EK9 IDE just before choosing Apply: The preview shows every change the refactoring makes; then the IDE formats each file it changed |
| Generate Dispatcher | The result | That is Generate Dispatcher: AnimalDispatcher gained sound() as dispatcher plus a private sound() overload for Dog and for Cat, each with a //AI: Implement sound lead where its body goes - exhaustive, since Animal is sealed; a non-sealed base instead leaves the entry's own fallback body to cover ... |
| Generate Dispatcher | Where this lesson comes from | For AI assistants - the MCP tool ek9_generate_dispatcher. |
| Extract to Localized Text | Extract to Localized Text | Extract to Localized Text moves a hard-coded string out of the code and into a localized text method, rewriting the call site to use the text variable already in scope. Here "Goodbye for now!" is hard-coded in ShowFarewell, when appText - the AppText text type's en_GB instance - already speaks ... |
| Extract to Localized Text | Step 1: Where it is | Put the caret on "Goodbye for now!", on line 17. The EK9 IDE once this is done: Put the caret on "Goodbye for now!", on line 17 |
| Extract to Localized Text | Step 2: Extract to Localized Text | Right-click it - or choose Refactor > Refactor This… - and choose Localisation > Extract to Localized Text… The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Localisation > Extract to Localized Text… Name the new method farewell, and the text ... |
| Extract to Localized Text | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. The EK9 IDE just before choosing Apply: The preview shows every change the refactoring makes; then the IDE formats each file it changed |
| Extract to Localized Text | The result | That is Extract to Localized Text: "Goodbye for now!" is gone from ShowFarewell, and AppText gained farewell() - one method, one body, for its one locale. A text type spanning several locales instead gets a stub per locale, listed for translation; a literal with no text type yet needs Code > ... |
| Extract to Localized Text | Where this lesson comes from | Answers - ek9 -q and the IDE's Answers tab: 113.For AI assistants - the MCP tool ek9_extract_to_localized_text. |
| Organize Localized Text | Organize Localized Text | Organize Localized Text gathers a module's localized text into one of three layouts: one file per locale, one file per text type, or everything collapsed into one file you name. Here greetings.ek9 declares Greeting for both en_GB and de inline, in the same file that runs it. To play it in the ... |
| Organize Localized Text | Step 1: Choose the layout | Choose Code > Localisation > Organize Localized Text… The EK9 IDE once this is done: Choose Code > Localisation > Organize Localized Text… |
| Organize Localized Text | Step 2: Split by Locale | Choose Split by Locale. That is one file per language, the layout Getting Started's localisation chapter uses. |
| Organize Localized Text | Step 3: Preview and apply | The preview shows a new file for each locale and the lines removed from greetings.ek9. Choose Apply. The EK9 IDE just before choosing Apply: The preview shows a new file for each locale and the lines removed from greetings.ek9 |
| Organize Localized Text | The result | That is Organize Localized Text: greetings.ek9 keeps only the program, and en_GB.ek9 and de.ek9 each hold their own locale's Greeting - one file per language, so adding a third locale is adding a third file. Split by Class gathers the same text the OTHER way, one file per text type, every locale ... |
| Organize Localized Text | Where this lesson comes from | Answers - ek9 -q and the IDE's Answers tab: 113, 1380.For AI assistants - the MCP tool ek9_organize_localized_text. |
| Inline Candidates | Inline Candidates | The Inline Candidates window finds locals whose name adds little over their initialiser - the inverse of Unused Code, and a self-audit against naming slop. Here reportLine declares two such locals: heading, a trivial literal used once, and total, which calls addTax() once. To play it in the IDE: ... |
| Inline Candidates | Step 1: Open the window | Choose View > Tool Windows > Inline Candidates. The EK9 IDE once this is done: Choose View > Tool Windows > Inline Candidates |
| Inline Candidates | Step 2: The findings | heading is listed under 🧹 Worth inlining - a trivial literal, used exactly once: a redundant name. total is listed under ✓ Safe - review first - its initialiser calls addTax(), so inlining it is mechanical, but the call it stands for may still be worth a name. The EK9 IDE once this is done: ... |
| Inline Candidates | Step 3: Inline one | Right-click heading and choose Inline variable… The EK9 IDE once this is done: Right-click heading and choose Inline variable… |
| Inline Candidates | Step 4: Preview and apply | The preview shows heading's value moved to where it was used, and the declaration gone. Choose Apply. |
| Inline Candidates | The result | That is the Inline Candidates window: heading is gone from reportLine, its literal "Daily Report" now written where heading was used, in the string rtn is given. total is left under Safe - review first: its initialiser calls addTax(), so inlining it is mechanical but the name addTax(100) stands ... |
| Inline Candidates | Where this lesson comes from | For AI assistants - the MCP tool ek9_find_inline_candidates, ek9_inline_variable. |
| Promote to Constant | Promote to Constant | Promote to Constant moves a name <- literal declaration - a property or a local - into the module's defines constant block, keeping the same name, and deletes the original declaration. Here temperature is Weather's own field, but 20 is the same for every Weather there will ever be: state that ... |
| Promote to Constant | Step 1: Where it is | Put the caret on temperature <- 20, on line 7. The EK9 IDE once this is done: Put the caret on temperature <- 20, on line 7 |
| Promote to Constant | Step 2: Promote to Constant | Right-click it - or choose Refactor > Refactor This… - and choose Promote to Constant… The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Promote to Constant… |
| Promote to Constant | Step 3: Preview and apply | The preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply. |
| Promote to Constant | The result | That is Promote to Constant: temperature is gone from Weather's own fields and lives in the module's defines constant block instead; show() still reads temperature - unqualified, it now resolves to the constant - so nothing else about Weather had to change. A value that DOES vary between ... |
| Promote to Constant | Where this lesson comes from | Answers - ek9 -q and the IDE's Answers tab: 140.For AI assistants - the MCP tool ek9_promote_to_constant. |
| Convert Constructor | Convert Constructor | Convert Constructor swaps a no-arg constructor between its two equivalent forms: 'default Name()' - the compiler's own shorthand - and an explicit body that sets every field with :=?. Here Person's no-arg constructor is 'default private', with nothing to customise yet. To play it in the IDE: Help ... |
| Convert Constructor | Step 1: The constructor | Put the caret on the default private Person() as pure line. The EK9 IDE once this is done: Put the caret on the default private Person() as pure line |
| Convert Constructor | Step 2: Expand it | Right-click it and choose Expand 'default' Constructor to Default-Setter. The EK9 IDE once this is done: Right-click it and choose Expand 'default' Constructor to Default-Setter The change is in the open file, not yet saved. Choose File > Save. The EK9 IDE once this is done: The change is in the ... |
| Convert Constructor | The result | That is Convert Constructor: Person's no-arg constructor is now explicit - private Person() as pure - with one this.field :=? String() per assignable field, ready to customise (add validation before the fields are set, say). Collapse Constructor to 'default' is the exact reverse, offered instead ... |
| Convert Constructor | Where this lesson comes from | For AI assistants - the MCP tool ek9_convert_constructor. |
| Expand Default Operator | Expand Default Operator | Expand Default Operator replaces a 'default operator' line (default operator $, == and the like) with the explicit body the compiler would synthesise from the fields - ready to customise. Here Point's default operator $ gives a string form nobody has looked at yet. To play it in the IDE: Help > ... |
| Expand Default Operator | Step 1: The default operator | Put the caret on the default operator $ line. The EK9 IDE once this is done: Put the caret on the default operator $ line |
| Expand Default Operator | Step 2: Expand it | Right-click it and choose Expand 'default operator $' to Skeleton. The EK9 IDE once this is done: Right-click it and choose Expand 'default operator $' to Skeleton The change is in the open file, not yet saved. Choose File > Save. The EK9 IDE once this is done: The change is in the open file, not ... |
| Expand Default Operator | The result | That is Expand Default Operator: Point's default operator $ is now an explicit body - operator $ as pure, interpolating every field in declaration order - ready to customise (a different format, say). Collapse to Default Operator is the exact reverse, offered instead on an explicit defaultable ... |
| Expand Default Operator | Where this lesson comes from | For AI assistants - the MCP tool ek9_expand_default_operator, ek9_collapse_to_default_operator. |
| Rename File / Move File | Rename File / Move File | Rename File and Move File relocate a file on disk, contents untouched - Rename edits the basename in place and enforces the .ek9 extension; Move edits the whole workspace-relative path, into another directory if you like, for any file. Here caller.ek9 references greet() from greeting.ek9; watch ... |
| Rename File / Move File | Step 1: Rename it | In the Project panel, right-click greeting.ek9, choose Rename File…, replace the name with greetings.ek9 and choose OK. The EK9 IDE just before choosing OK: In the Project panel, right-click greeting.ek9, choose Rename File…, replace the name with greetings.ek9 and choose OK |
| Rename File / Move File | Step 2: Move it | In the Project panel, right-click greetings.ek9, choose Move File…, replace the path with lib/greetings.ek9 and choose OK. The EK9 IDE just before choosing OK: In the Project panel, right-click greetings.ek9, choose Move File…, replace the path with lib/greetings.ek9 and choose OK |
| Rename File / Move File | The result | That is Rename File and Move File: greeting.ek9 is now lib/greetings.ek9, and caller.ek9 - which never changed - still resolves greet() exactly as before. EK9 module identity comes from the file's own 'defines module' line, never its name or directory, so neither tool touches a single byte of ... |
| Rename File / Move File | Where this lesson comes from | For AI assistants - the MCP tool ek9_rename_file, ek9_move_file. |
| Toggle Comment, Remove Comment, Reformat | Toggle Comment, Remove Comment, Reformat | Toggle Comment, Remove Comment, Reformat File and Reformat All Open Files are code-tidying actions with no dialog and no preview - each change lands at once, so each gets its own Save afterwards. Toggle Comment wraps whole lines in EK9's <!- -!> block-comment form, disabling them without deleting ... |
| Toggle Comment, Remove Comment, Reformat | Step 1: Toggle Comment | Put the caret on the second stdout.println line - the debug print, not the greeting - then choose Code > Toggle Comment (⌘/), also on the right-click menu. It wraps the line in EK9's <!- -!> block-comment form, so it stops running without being deleted. The EK9 IDE once this is done: Put the ... |
| Toggle Comment, Remove Comment, Reformat | Step 2: Remove Comment | Right-click the comment line - // This comment is no longer needed - and choose Remove Comment. The EK9 IDE once this is done: Right-click the comment line - // This comment is no longer needed - and choose Remove Comment The change is in the open file, not yet saved. Choose File > Save. The EK9 ... |
| Toggle Comment, Remove Comment, Reformat | Step 3: Reformat File | A quick edit has left extra spaces inside stdout.println's brackets - stdout.println( greeting ). The program still compiles; it just no longer reads as EK9's canonical layout. The EK9 IDE once this is done: A quick edit has left extra spaces inside stdout.println's brackets - stdout.println( ... |
| Toggle Comment, Remove Comment, Reformat | Step 4: Reformat All Open Files | greet.ek9 - the function tidy.ek9 calls - is now open too, with the same kind of extra spacing: two spaces after rtn as String:. It is not saved either. The EK9 IDE once this is done: greet.ek9 - the function tidy.ek9 calls - is now open too, with the same kind of extra spacing tidy.ek9 is back ... |
| Toggle Comment, Remove Comment, Reformat | The result | That is Toggle Comment, Remove Comment, Reformat File and Reformat All Open Files: the debug print is commented out rather than deleted, the stale note is gone, and every spacing slip in both open files is back to canonical style. Toggle Comment is Code > Toggle Comment (⌘/) or the right-click ... |
| Toggle Comment, Remove Comment, Reformat | Where this lesson comes from | Answers - ek9 -q and the IDE's Answers tab: 18, 625.For AI assistants - the MCP tool ek9_toggle_block_comment, ek9_remove_comments, ek9_format. |
| New EK9 File, New Directory, Delete File, Delete Directory | New EK9 File, New Directory, Delete File, Delete Directory | The Project panel's own right-click menu makes and removes files and directories directly on disk - no dialog preview, no changeset. New EK9 File… writes the three-part EK9 boilerplate before you type a line of your own; New Directory… just makes a folder; Delete File… and Delete Directory… each ... |
| New EK9 File, New Directory, Delete File, Delete Directory | Step 1: A new file | Right-click archive in the Project panel, choose New EK9 File…, name it report.ek9, name its module lesson.archive.report, and choose OK. The EK9 IDE just before choosing OK: Right-click archive in the Project panel, choose New EK9 File…, name it report.ek9, name its module lesson.archive.report, ... |
| New EK9 File, New Directory, Delete File, Delete Directory | Step 2: A new directory | Right-click archive again, choose New Directory…, name it scratch, and choose OK. The EK9 IDE just before choosing OK: Right-click archive again, choose New Directory…, name it scratch, and choose OK |
| New EK9 File, New Directory, Delete File, Delete Directory | Step 3: Delete it again | Right-click scratch and choose Delete Directory… - enabled only because it is empty - then choose OK. The EK9 IDE just before choosing OK: Right-click scratch and choose Delete Directory… - enabled only because it is empty - then choose OK |
| New EK9 File, New Directory, Delete File, Delete Directory | Step 4: Delete the old file | Right-click old_notes.ek9 and choose Delete File…, then choose Delete. The EK9 IDE just before choosing Delete: Right-click old_notes.ek9 and choose Delete File…, then choose Delete |
| New EK9 File, New Directory, Delete File, Delete Directory | The result | That is the Project panel's own file operations: report.ek9 is new in archive, scratch existed only long enough to prove Delete Directory… only ever removes an EMPTY one, and old_notes.ek9 - no longer needed - is gone too. New EK9 File… writes the same three-part boilerplate ek9_write_file does - ... |
| New EK9 File, New Directory, Delete File, Delete Directory | Where this lesson comes from | For AI assistants - the MCP tool ek9_write_file, ek9_delete_file, ek9_delete_directory. |
| The Journal: one run | The Journal: one run | The Journal records every change to a value while a program runs, so a failure can be read backwards to where it went wrong. This lesson records one run of Orders, a small program that fails late. Read Orders.ek9 first. To play it in the IDE: Help > Lessons > Debugging and the Journal…, or ek9 ... |
| The Journal: one run | Step 1: A program that fails late | Orders runs an order through scenario 1, 2, 3 or 4. Scenario 3 - a discount, then a refund - fails late: the invoice refuses a negative total with a Panic, long after the change that made it negative. Nothing fails where the mistake is. The EK9 IDE once this is done: Orders runs an order through ... |
| The Journal: one run | Step 2: Record a run | Choose Run > New Journal Investigation… The EK9 IDE once this is done: Choose Run > New Journal Investigation… Watch Order.total, and give one input set - 3, the failing scenario: one line is one run. The hypothesis - what you think went wrong - is optional; this lesson gives one. Choose Start. ... |
| The Journal: one run | Step 3: The story | A failed run opens at its story: the run's inputs, then the changes to Order.total that led to the failure, oldest first, each with its tick - t1, t2, ... - the order they happened in. Read it from the bottom: the symptom, then the change just before it. The EK9 IDE once this is done: A failed ... |
| The Journal: one run | Step 4: Where it went wrong | Click Orders.ek9:41 in the story - the refund that took the total from 50 to -30. The editor goes to that line. The EK9 IDE once this is done: Click Orders.ek9:41 in the story - the refund that took the total from 50 to -30 |
| The Journal: one run | Step 5: The marks in the editor | In the editor, each line that changed Order.total shows what it did in this run - total 50 -> -30 and its tick. A count in the margin marks every line that could change it: how often it did in this run (a 0 on one it never reached). The red ! is where it failed. The EK9 IDE once this is done: In ... |
| The Journal: one run | The result | That is one run read backwards: from where it failed to the change that caused it. Comparing it with runs that passed - what only the failing run did - is the next lesson. |
| The Journal: one run | Where this lesson comes from | For AI assistants - the MCP tool ek9_debug_inspect. |
| The Journal: comparing runs | The Journal: comparing runs | Comparing finds what separates the runs that fail from the ones that pass, without reading any one run's story first. This lesson records all four of Orders' scenarios, then compares the one that fails with one that passes. Read Orders.ek9 first. To play it in the IDE: Help > Lessons > Debugging ... |
| The Journal: comparing runs | Step 1: A program with passing and failing runs | Orders runs scenario 1, 2, 3 or 4: an add, then (scenario 2 or 3) a discount, then (scenario 3 or 4) a refund. Scenario 3 - discount, then refund - is the only one that fails: the refund is taken from the discounted total, and the invoice refuses the negative result. The EK9 IDE once this is ... |
| The Journal: comparing runs | Step 2: Record several runs | Choose Run > New Journal Investigation… The EK9 IDE once this is done: Choose Run > New Journal Investigation… Watch Order.total, and give all four scenarios - one input set per line: 1, 2, 3, 4. Choose Start. The EK9 IDE just before choosing Start: Watch Order.total, and give all four scenarios ... |
| The Journal: comparing runs | Step 3: Choose two to compare | Click the FAIL run (scenario 3) to select it alone, then ⌘-click the pass run for scenario 1: now exactly those two are selected, and compared - not all four. The EK9 IDE once this is done: Click the FAIL run (scenario 3) to select it alone, then ⌘-click the pass run for scenario 1 |
| The Journal: comparing runs | Step 4: What only the failing run did | The side by side lines up the failing run against the passing one, step by step. "not in this run" under pass, for the discount and the refund, is what only the failing run did - read from the top: the add is the same in both, then the failing run alone discounts and refunds. The EK9 IDE once ... |
| The Journal: comparing runs | Step 5: The Journal Report | Choose Report… The EK9 IDE once this is done: Choose Report… Say what you think is wrong - citing the step and line that show it - and choose Write Report. It opens as a page: what was run, how each run ended, and the two side by side - with report.json beside it for a model to read. The EK9 IDE ... |
| The Journal: comparing runs | The result | That is comparing: choose the runs, read what separates them, and hand the report to someone who has not seen the IDE. Trying a variation of one run - without filling the whole dialog again - is the next lesson. The EK9 IDE when the lesson has finished |
| The Journal: comparing runs | Where this lesson comes from | For AI assistants - the MCP tool ek9_debug_inspect. |
| The Journal: a new investigation | The Journal: a new investigation | Trying a variation of a run - a different input, everything else the same - usually means filling New Journal Investigation… from scratch. The Journal has a shortcut: run it again with one input changed. This lesson records Orders' failing scenario, then tries scenario 4 instead, with the same ... |
| The Journal: a new investigation | Step 1: Orders, and its defect | Orders runs scenario 1, 2, 3 or 4: an add, then (scenario 2 or 3) a discount, then (scenario 3 or 4) a refund. Only scenario 3 fails - the refund is taken from the discounted total. Scenario 4 refunds too, but with no discount first. The EK9 IDE once this is done: Orders runs scenario 1, 2, 3 or 4 |
| The Journal: a new investigation | Step 2: Record one failing run | Choose Run > New Journal Investigation… The EK9 IDE once this is done: Choose Run > New Journal Investigation… Watch Order.total, and give one input set - 3, the failing scenario. Choose Start. The EK9 IDE just before choosing Start: Watch Order.total, and give one input set - 3, the failing ... |
| The Journal: a new investigation | Step 3: Try it again, one input changed | Right-click the run and choose "Again with one input changed…" The EK9 IDE once this is done: Right-click the run and choose "Again with one input changed…" Change the input to 4 and choose Run. It runs again with the same seed, so only that input differs. The EK9 IDE just before choosing Run: ... |
| The Journal: a new investigation | Step 4: What changed | Both runs are in the Journal tab: scenario 3 - FAIL, with its symptom - and scenario 4 - pass, with none. Same program, same seed, one input changed: the discount is what the failing run did differently. The line above the table sums up the latest investigation only - the one run just made. The ... |
| The Journal: a new investigation | The result | That is the Journal's own way to try a variation of a run - the same seed, one input changed, without filling New Journal Investigation… again. Comparing runs deliberately, and the Journal Report, are the earlier lessons. |
| The Journal: a new investigation | Where this lesson comes from | For AI assistants - the MCP tool ek9_debug_session. |
| Show Blast Radius | Show Blast Radius | Show Blast Radius pictures who a purity change would reach before you make it. Here announce() is pure but calls shout(), which is not (E08130); morningBriefing() and eveningBriefing() are both pure callers of announce(), in two different files - read the code. To play it in the IDE: Help > ... |
| Show Blast Radius | Step 1: Where the change starts | Put the caret on shout(message), on line 12 - where the compiler flagged it. The EK9 IDE once this is done: Put the caret on shout(message), on line 12 - where the compiler flagged it |
| Show Blast Radius | Step 2: Show Blast Radius | Right-click it - or choose Refactor > Refactor This… - and choose Show Blast Radius (purity impact). The EK9 IDE once this is done: Right-click it - or choose Refactor > Refactor This… - and choose Show Blast Radius (purity impact) |
| Show Blast Radius | Step 3: The ripple | The Fix dropdown starts at Drop pure from announce(). announce() sits at the centre, ▼ shout() to its right (the non-pure callee - what Make callee pure would change), and ▲ morningBriefing() and eveningBriefing() to its left (the pure callers that break if pure is dropped from announce()) - a ... |
| Show Blast Radius | Step 4: The other direction | Choose Make callee pure in the Fix dropdown - making shout() pure, instead of announce() not. Apply turns from disabled to enabled: nothing else breaks, so this direction is ready. The EK9 IDE once this is done: Choose Make callee pure in the Fix dropdown - making shout() pure, instead of ... |
| Show Blast Radius | The result | That is Show Blast Radius: removing pure from announce() would break 2 callers in 2 files - morningBriefing() and eveningBriefing() - so EK9 refuses it outright for this direction; adding pure to shout() instead breaks nothing, and is the one Apply offers. Fix Purity Contract plays that Apply, ... |
| Show Blast Radius | Where this lesson comes from | The errors it fixes - each one's explanation offers this lesson: E05150, E05160, E08130.For AI assistants - the MCP tool ek9_query_purity_impact, ek9_query_signature_impact. |
| Capabilities | Capabilities | The Capabilities window audits every gated system type the code uses against what the package declares. Here printMessage uses Stdout and logError uses Stderr - neither declared, each its own E12010, explained in the Hovers panel - while the package declares TCP, which nothing ever uses. To play ... |
| Capabilities | Step 1: Open the window | Choose View > Tool Windows > Capabilities. The EK9 IDE once this is done: Choose View > Tool Windows > Capabilities |
| Capabilities | Step 2: The audit | Stdout and Stderr are both listed under ⚠ under-declared - used but not declared, the E12010 set. TCP is listed under ⚠ over-declared, unused - declared but nothing ever calls it. |
| Capabilities | Step 3: Add a capability | Right-click Stdout and choose Add capability 'Stdout' to package. The EK9 IDE once this is done: Right-click Stdout and choose Add capability 'Stdout' to package |
| Capabilities | Step 4: Preview and apply | The preview shows Stdout added to the capabilities list; then the IDE formats the file. Choose Apply. |
| Capabilities | Step 5: Remove an unused capability | Right-click TCP and choose Remove unused capability 'TCP'. The EK9 IDE once this is done: Right-click TCP and choose Remove unused capability 'TCP' |
| Capabilities | Step 6: Preview and apply | The preview shows TCP removed from the capabilities list; then the IDE formats the file. Choose Apply. |
| Capabilities | The result | That is the Capabilities window: Stdout is now declared, so printMessage's own E12010 is gone; TCP is gone from the capabilities list entirely, since nothing ever used it. Stderr's own E12010 - the same fix, one finding down - is left for you to try. Under-declared is the compile-blocking set ... |
| Capabilities | Where this lesson comes from | The errors it fixes - each one's explanation offers this lesson: E12010.Answers - ek9 -q and the IDE's Answers tab: 1271, 1277, 1275.For AI assistants - the MCP tool ek9_query_capability_usage, ek9_add_capability, ek9_remove_capability. |