Search the IDE pages

Every section of the IDE pages, with its text. Type to narrow the list; every word must match.

PageSectionText
The EK9 IDEThe EK9 IDEThe 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 IDEWhat you needek9 -ide starts the IDE. Like the rest of EK9, it needs Java 25 or later.
The EK9 IDEA first programYour 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 IDEThe lessonsThe 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 IDEGetting startedYour 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 IDEFindingSearch 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 IDEWriting codeNew 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 IDERefactoringRename, 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 IDEDebugging and the JournalBreakpoints 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 IDEUnderstanding a codebaseThe 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 IDESecurity, packages and GitSanitised 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 IDEFixing errorsEvery 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 IDEThe menusEach 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 IDEUsing VS Code or IntelliJ insteadThe 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 IDEThe languageThis section covers the IDE. The language itself is in the EK9 language reference, starting with Structure.
Your first projectYour first projectThis 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 projectThe IDE as it first opensStart 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 projectStep 1: A new projectA 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 projectStep 2: A new EK9 fileIn 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 projectStep 3: The example programHelp > 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 projectStep 4: Paste it inIn 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 projectStep 5: Run itClick 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 projectNextThe 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: textFind: textThe 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: textStep 1: Type to searchChoose 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: textStep 2: Step through the matchesChoose 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: textStep 3: Whole wordTurn 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: textStep 4: Match caseTurn 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: textThe resultThat 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 replaceFind: regex replaceThe 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 replaceStep 1: Open ReplaceChoose Edit > Replace… The EK9 IDE once this is done: Choose Edit > Replace…
Find: regex replaceStep 2: A regular expressionTurn 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 replaceStep 3: Replace with a capture groupType $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 replaceThe resultThat 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: symbolsFind: symbolsText 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: symbolsStep 1: Text mode, for contrastChoose 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: symbolsStep 2: Switch to SymbolsChoose 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: symbolsStep 3: The three kind chipsClick 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: symbolsStep 4: Declared, Read, WrittenTurn 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: symbolsThe resultThat 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: symbolsReplace: symbolsReplace 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: symbolsStep 1: Find the localChoose 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: symbolsStep 2: Rename itType 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: symbolsStep 3: Preview and applyThe preview shows every place total becomes runningTotal. Choose Apply.
Replace: symbolsThe resultThat 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: symbolsWhere this lesson comes fromFor AI assistants - the MCP tool ek9_rename_symbol.
Find in ProjectFind in ProjectEdit > 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 ProjectStep 1: Open Find in ProjectChoose 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 ProjectStep 2: List, and jump to a resultChoose 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 ProjectStep 3: Narrow to ModuleChange 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 ProjectStep 4: Narrow to FileChange 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 ProjectThe resultThat 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 wayFind your wayFind 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 wayStep 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 wayStep 2: Find ReferencesPut 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 wayThe resultFind 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, builtChapter 16: a class, builtChapter 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, builtStep 1: A classChoose 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, builtStep 2: A fieldRight-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, builtStep 3: tick — and its logicRight-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, builtStep 4: total — and its logicRight-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, builtStep 5: The programChoose 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, builtStep 6: Run itChoose 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, builtThe resultCounter.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, builtWhere this lesson comes fromFor AI assistants - the MCP tool ek9_new_construct, ek9_add_field, ek9_add_method, ek9_add_program.
Chapter 4: a function, builtChapter 4: a function, builtChapter 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, builtStep 1: A functionChoose 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, builtStep 2: Its comment, and its logicSelect 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, builtStep 3: The programChoose 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, builtStep 4: Run itChoose 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, builtThe resultAnnounce.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, builtWhere this lesson comes fromFor AI assistants - the MCP tool ek9_new_construct, ek9_add_program.
Chapter 14: an enumeration, builtChapter 14: an enumeration, builtChapter 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, builtStep 1: An enumerationChoose 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, builtStep 2: kindOf — and its logicChoose 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, builtStep 3: The program — and its logicChoose 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, builtStep 4: Run itChoose 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, builtThe resultDays.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, builtWhere this lesson comes fromFor AI assistants - the MCP tool ek9_new_construct, ek9_add_program.
Chapter 14: a record, builtChapter 14: a record, builtChapter 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, builtStep 1: A record, with its fieldsChoose 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, builtStep 2: Building it blank, then complete — and its logicRight-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, builtStep 3: moveTo — and its logicChoose 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, builtStep 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, builtStep 5: The program — and its logicChoose 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, builtStep 6: Run itChoose 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, builtThe resultCoord.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, builtWhere this lesson comes fromFor AI assistants - the MCP tool ek9_new_construct, ek9_add_constructor, ek9_add_operator, ek9_add_program.
Create Dynamic FunctionCreate Dynamic FunctionCreate 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 FunctionStep 1: Where it goesPut 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 FunctionStep 2: Create the closureRight-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 FunctionStep 3: Preview and applyThe 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 FunctionStep 4: Use itA 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 FunctionThe resultThat 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 FunctionWhere this lesson comes fromAnswers - ek9 -q and the IDE's Answers tab: 52.For AI assistants - the MCP tool ek9_create_dynamic_function.
Create Dynamic ClassCreate Dynamic ClassCreate 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 ClassStep 1: Where it goesPut 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 ClassStep 2: Create the classRight-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 ClassStep 3: Preview and applyThe 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 ClassStep 4: Use itAn 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 ClassThe resultThat 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 ClassWhere this lesson comes fromAnswers - ek9 -q and the IDE's Answers tab: 1126.For AI assistants - the MCP tool ek9_create_dynamic_class.
Chapter 3: a loop, reshapedChapter 3: a loop, reshapedChapter 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, reshapedStep 1: The programChoose 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, reshapedStep 2: A plain startSelect 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, reshapedStep 3: Loop it with Surround WithPut 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, reshapedStep 4: Run itChoose 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, reshapedThe resultCountdown.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, reshapedWhere this lesson comes fromFor AI assistants - the MCP tool ek9_new_construct, ek9_surround_with.
Chapter 17: an abstract type and its subtypes, builtChapter 17: an abstract type and its subtypes, builtChapter 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, builtStep 1: A constantChoose 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, builtStep 2: An abstract typeChoose 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, builtStep 3: Circle — a subtypeChoose 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, builtStep 4: Rectangle — another subtypeChoose 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, builtStep 5: The programChoose 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, builtStep 6: Run itChoose 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, builtThe resultShapes.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, builtWhere this lesson comes fromFor 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, builtChapter 18: traits and delegation, builtChapter 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, builtStep 1: A traitChoose 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, builtStep 2: Home — implementing itChoose 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, builtStep 3: Framed — the field and delegationChoose 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, builtStep 4: Framed — construction and bodySelect 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, builtStep 5: The programChoose 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, builtStep 6: Run itChoose 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, builtThe resultDelegate.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, builtWhere this lesson comes fromFor 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, builtChapter 21: operators, builtChapter 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, builtStep 1: A record, with its fieldsChoose 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, builtStep 2: Its constructor — and its logicRight-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, builtStep 3: operator + — a custom operator, and its logicRight-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, builtStep 4: operator $ — and its logicRight-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, builtStep 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, builtStep 6: The programChoose 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, builtStep 7: Run itChoose 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, builtThe resultVectors.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, builtWhere this lesson comes fromFor 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 fieldChoose 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 logicRight-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 logicRight-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 logicRight-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 promotionsChoose 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 itChoose 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 resultCelsius.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 fromFor AI assistants - the MCP tool ek9_new_construct, ek9_add_constructor, ek9_add_operator, ek9_add_program.
Chapter 19: a component, builtChapter 19: a component, builtChapter 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, builtStep 1: TaxTable — and surchargeChoose 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, builtStep 2: basePriceChoose 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, builtStep 3: Pricing — the interfaceChoose 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, builtStep 4: StandardPricing — and its logicChoose 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, builtStep 5: The programChoose 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, builtStep 6: Run itChoose 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, builtThe resultPricing.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, builtWhere this lesson comes fromFor AI assistants - the MCP tool ek9_new_construct, ek9_add_method, ek9_add_program.
Chapter 5: tests, builtChapter 5: tests, builtChapter 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, builtStep 1: square — a pure functionChoose 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, builtStep 2: cube — a pure functionChoose 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, builtStep 3: Where tests liveOpen 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, builtStep 4: SquareTestChoose 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, builtStep 5: CubeTestChoose 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, builtStep 6: Run the testsRun ▸ 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, builtStep 7: Generate Edge-Case TestsChoose 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, builtThe resultmaths.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, builtWhere this lesson comes fromFor AI assistants - the MCP tool ek9_new_construct, ek9_add_program, ek9_run_tests, ek9_generate_edge_case_tests.
Chapter 2: values, reshapedChapter 2: values, reshapedChapter 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, reshapedStep 1: The programChoose 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, reshapedStep 2: A plain startSelect 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, reshapedStep 3: Inline VariablePut 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, reshapedStep 4: Extract VariableSelect 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, reshapedStep 5: Run itChoose 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, reshapedThe resultValues.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, reshapedWhere this lesson comes fromFor AI assistants - the MCP tool ek9_add_program, ek9_inline_variable, ek9_extract_variable.
Chapter 12: a pipeline, builtChapter 12: a pipeline, builtChapter 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, builtStep 1: isEven — a pure functionChoose 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, builtStep 2: doubleIt — a pure functionChoose 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, builtStep 3: The programChoose 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, builtStep 4: Read the pipelinePut 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, builtStep 5: Run itChoose 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, builtThe resultNumbers.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, builtWhere this lesson comes fromFor AI assistants - the MCP tool ek9_new_construct, ek9_add_program, ek9_query_pipeline.
Chapter 10: guards, reshapedChapter 10: guards, reshapedChapter 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, reshapedStep 1: lookupNameChoose 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, reshapedStep 2: storedNameChoose 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, reshapedStep 3: messagePrefixChoose 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, reshapedStep 4: Greet — a guard, twiceChoose 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, reshapedStep 5: GreetLongNames — a guard with a conditionChoose 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, reshapedStep 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, reshapedStep 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, reshapedStep 8: Run itChoose 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, reshapedThe resultGuards.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, reshapedWhere this lesson comes fromFor AI assistants - the MCP tool ek9_new_construct, ek9_add_program, ek9_apply_guard_pattern.
Chapter 11: Optional and Result, builtChapter 11: Optional and Result, builtChapter 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, builtStep 1: safeDivide — a pure function returning ResultChoose 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, builtStep 2: Divide by zero, with Surround WithPut 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, builtStep 3: The programChoose 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, builtStep 4: Read Result's effective APISelect 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, builtStep 5: Run itChoose 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, builtThe resultDivide.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, builtWhere this lesson comes fromFor AI assistants - the MCP tool ek9_new_construct, ek9_surround_with, ek9_add_program, ek9_query_effective_api.
Chapter 15: a constrained type, builtChapter 15: a constrained type, builtChapter 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, builtStep 1: A constrained typeChoose 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, builtStep 2: verdict — and its logicChoose 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, builtStep 3: The program — and its logicChoose 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, builtStep 4: Run itChoose 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, builtThe resultDrivingAge.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, builtWhere this lesson comes fromFor AI assistants - the MCP tool ek9_new_construct, ek9_add_program.
Chapter 7: asking about a typeChapter 7: asking about a typeChapter 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 typeStep 1: The programChoose 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 typeStep 2: Ask: /h DimensionType /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 typeStep 3: Ask: Effective APISelect 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 typeStep 4: Run itChoose 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 typeThe resultMeasures.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 typeWhere this lesson comes fromFor AI assistants - the MCP tool ek9_new_construct, ek9_add_program, ek9_help, ek9_query_effective_api.
Chapter 8: a text type, builtChapter 8: a text type, builtChapter 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, builtStep 1: The program, hard-coding EnglishChoose 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, builtStep 2: announce - the real messageSelect 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, builtStep 3: Adding FrenchChoose 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, builtStep 4: Adding GermanChoose 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, builtStep 5: Every languageThree 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, builtStep 6: Run itChoose 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, builtThe resultBirthday.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, builtWhere this lesson comes fromFor AI assistants - the MCP tool ek9_add_program, ek9_extract_to_localized_text, ek9_edit_localized_text.
Chapter 9: collections, asked aboutChapter 9: collections, asked aboutChapter 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 aboutStep 1: The programChoose 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 aboutStep 2: Ask: /q 129Type /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 aboutStep 3: Read Effective API: ListSelect 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 aboutStep 4: Read Effective API: DictSelect 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 aboutStep 5: Run itChoose 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 aboutThe resultBasket.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 aboutWhere this lesson comes fromAnswers - 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, readChapter 20: a generic type, readChapter 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, readStep 1: The programChoose 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, readStep 2: Read names's Type HierarchySelect 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, readStep 3: Read primes's Effective APISelect 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, readStep 4: Run itChoose 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, readThe resultGenerics.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, readWhere this lesson comes fromFor 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, builtChapter 22: a program with arguments, builtChapter 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, builtStep 1: NoteLink — the programChoose 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, builtStep 2: Run it, with an argumentChoose 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, builtStep 3: Run it again, from a saved configurationChoose 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, builtThe resultNoteLink.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, builtWhere this lesson comes fromFor AI assistants - the MCP tool ek9_add_program, ek9_run_program.
Chapter 23: the game, built and playedChapter 23: the game, built and playedChapter 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 playedStep 1: Score — a record, with its fieldsChoose 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 playedStep 2: Building a Score, blank then completeRight-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 playedStep 3: Score's own operatorsRight-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 playedStep 4: Game — a class, with its first fieldsChoose 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 playedStep 5: Building a Game, blank then completeRight-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 playedStep 6: guess — taking one guessRight-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 playedStep 7: over, triesUsed and reportRight-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 playedStep 8: hint and rank — two pure functionsChoose 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 playedStep 9: The board helpersChoose 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 playedStep 10: playerName — reading the command lineChoose 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 playedStep 11: The program — a thin shellChoose 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 playedStep 12: Playing it, through the debuggerClick 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 playedThe resultGuess.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 playedWhere this lesson comes fromFor 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 JournalChapter 23: running the tests, and the JournalChapter 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 JournalStep 1: Running the testsRun ▸ 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 JournalStep 2: The JournalChoose 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 JournalThe resultAll 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 JournalWhere this lesson comes fromFor AI assistants - the MCP tool ek9_run_tests, ek9_debug_inspect.
Extract ConstantExtract ConstantExtract 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 ConstantStep 1: Where it isPut the caret on 18, on line 8. The EK9 IDE once this is done: Put the caret on 18, on line 8
Extract ConstantStep 2: Extract ConstantRight-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 ConstantStep 3: Preview and applyThe 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 ConstantThe resultThat 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 ConstantWhere this lesson comes fromThe 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 SymbolRename SymbolRename 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 SymbolStep 1: Where it isPut the caret on temp, on line 8. The EK9 IDE once this is done: Put the caret on temp, on line 8
Rename SymbolStep 2: Rename SymbolChoose 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 SymbolStep 3: Preview and applyThe 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 SymbolThe resultThat 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 SymbolWhere this lesson comes fromThe 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 VariableExtract VariableExtract 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 VariableStep 1: The expressionSelect (first ?: second) <? third, on line 12. The EK9 IDE once this is done: Select (first ?: second) <? third, on line 12
Extract VariableStep 2: Extract VariableChoose 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 VariableStep 3: Preview and applyThe 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 VariableThe resultThat 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 VariableWhere this lesson comes fromThe 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 SignatureChange SignatureChange 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 SignatureStep 1: Where it isPut the caret on unusedOneOfTwo, on line 11. The EK9 IDE once this is done: Put the caret on unusedOneOfTwo, on line 11
Change SignatureStep 2: Change SignatureChoose 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 SignatureStep 3: Preview and applyThe 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 SignatureThe resultThat 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 SignatureWhere this lesson comes fromThe 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 MethodExtract MethodExtract 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 MethodStep 1: The statementsSelect 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 MethodStep 2: Extract MethodChoose 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 MethodStep 3: Preview and applyThe 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 MethodThe resultThat 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 MethodWhere this lesson comes fromThe 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 DeleteSafe DeleteSafe 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 DeleteStep 1: Where it isPut the caret on doWork, on line 11. The EK9 IDE once this is done: Put the caret on doWork, on line 11
Safe DeleteStep 2: Safe DeleteChoose Refactor > Safe Delete… The EK9 IDE once this is done: Choose Refactor > Safe Delete…
Safe DeleteStep 3: Preview and applyThe preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply.
Safe DeleteThe resultThat 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 DeleteWhere this lesson comes fromThe 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 CodeUnused CodeThe 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 CodeStep 1: Open the windowChoose View > Tool Windows > Unused Code. The EK9 IDE once this is done: Choose View > Tool Windows > Unused Code
Unused CodeStep 2: The findingsforgottenHelper 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 CodeStep 3: Delete it safelyRight-click forgottenHelper and choose Delete safely… The EK9 IDE once this is done: Right-click forgottenHelper and choose Delete safely…
Unused CodeStep 4: Preview and applyThe preview shows forgottenHelper's declaration gone, with nothing else to change - nothing else used it. Choose Apply.
Unused CodeThe resultThat 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 CodeWhere this lesson comes fromFor AI assistants - the MCP tool ek9_find_unused_code, ek9_safe_delete.
Organize ConstantsOrganize ConstantsOrganize 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 ConstantsStep 1: Where it isPut 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 ConstantsStep 2: Organize ConstantsChoose 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 ConstantsStep 3: Preview and applyThe 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 ConstantsThe resultThat 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 ConstantsWhere this lesson comes fromThe 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 ReferencesOrganize ReferencesOrganize 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 ReferencesStep 1: Where it isPut the caret on polish, on line 5. The EK9 IDE once this is done: Put the caret on polish, on line 5
Organize ReferencesStep 2: Organize ReferencesRight-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 ReferencesStep 3: Preview and applyThe preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply.
Organize ReferencesThe resultThat 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 ReferencesWhere this lesson comes fromFor AI assistants - the MCP tool ek9_organize_references.
Sync ReferencesSync ReferencesSync 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 ReferencesStep 1: Where it isPut the caret on prune, on line 5. The EK9 IDE once this is done: Put the caret on prune, on line 5
Sync ReferencesStep 2: Sync ReferencesRight-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 ReferencesStep 3: Preview and applyThe preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply.
Sync ReferencesThe resultThat 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 ReferencesWhere this lesson comes fromFor AI assistants - the MCP tool ek9_sync_references.
Inline VariableInline VariableInline 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 VariableStep 1: Where it isPut the caret on total, on line 12. The EK9 IDE once this is done: Put the caret on total, on line 12
Inline VariableStep 2: Inline VariableChoose Refactor > Inline Variable. The EK9 IDE once this is done: Choose Refactor > Inline Variable
Inline VariableStep 3: Preview and applyThe preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply.
Inline VariableThe resultThat 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 VariableWhere this lesson comes fromFor AI assistants - the MCP tool ek9_inline_variable.
Introduce ParameterIntroduce ParameterIntroduce 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 ParameterStep 1: The expressionSelect STANDARD_RATE, on line 11. The EK9 IDE once this is done: Select STANDARD_RATE, on line 11
Introduce ParameterStep 2: Introduce ParameterChoose 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 ParameterStep 3: Preview and applyThe 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 ParameterThe resultThat 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 ParameterWhere this lesson comes fromFor AI assistants - the MCP tool ek9_introduce_parameter.
Inline FunctionInline FunctionInline 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 FunctionStep 1: Where it isPut the caret on welcome, on line 10. The EK9 IDE once this is done: Put the caret on welcome, on line 10
Inline FunctionStep 2: Inline FunctionChoose Refactor > Inline Function… The EK9 IDE once this is done: Choose Refactor > Inline Function…
Inline FunctionStep 3: Preview and applyThe preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply.
Inline FunctionThe resultThat 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 FunctionWhere this lesson comes fromFor AI assistants - the MCP tool ek9_inline_function.
Move ConstructMove ConstructMove 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 ConstructStep 1: Where it isPut the caret on priceLabel, on line 9. The EK9 IDE once this is done: Put the caret on priceLabel, on line 9
Move ConstructStep 2: Move ConstructChoose 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 ConstructStep 3: Preview and applyThe 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 ConstructThe resultThat 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 ConstructWhere this lesson comes fromFor AI assistants - the MCP tool ek9_move_construct.
Lift into GuardLift into GuardLift 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 GuardStep 1: Where it isPut the caret on greeting?, on line 18. The EK9 IDE once this is done: Put the caret on greeting?, on line 18
Lift into GuardStep 2: Lift into GuardRight-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 GuardStep 3: Preview and applyThe preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply.
Lift into GuardThe resultThat 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 GuardWhere this lesson comes fromAnswers - ek9 -q and the IDE's Answers tab: 971, 1146.For AI assistants - the MCP tool ek9_apply_guard_pattern.
Wrap with coalescingWrap with coalescingWrap 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 coalescingStep 1: The expressionSelect name, on line 9. The EK9 IDE once this is done: Select name, on line 9
Wrap with coalescingStep 2: Wrap with coalescingRight-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 coalescingStep 3: Preview and applyThe 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 coalescingThe resultThat 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 coalescingWhere this lesson comes fromAnswers - ek9 -q and the IDE's Answers tab: 243, 1059, 1067.For AI assistants - the MCP tool ek9_insert_coalescing.
Make OpenMake OpenChange 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 OpenStep 1: Where it isPut the caret on Shape, on line 6. The EK9 IDE once this is done: Put the caret on Shape, on line 6
Make OpenStep 2: Make OpenRight-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 OpenStep 3: Preview and applyThe preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply.
Make OpenThe resultThat 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 OpenWhere this lesson comes fromThe 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 ContractFix Purity ContractFix 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 ContractStep 1: Where the error isPut 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 ContractStep 2: Blast Radius: the fix it offersChoose 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 ContractStep 3: Preview and applyThe 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 ContractThe resultThat 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 ContractWhere this lesson comes fromThe 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 MethodsImplement MethodsImplement 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 MethodsStep 1: Where it isPut the caret on C6, on line 65. The EK9 IDE once this is done: Put the caret on C6, on line 65
Implement MethodsStep 2: Implement MethodsRight-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 MethodsStep 3: Preview and applyThe preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply.
Implement MethodsThe resultThat 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 MethodsWhere this lesson comes fromThe 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 ConcatenationRewrite String ConcatenationRewrite 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 ConcatenationStep 1: Where it isPut the caret on Hello, on line 9. The EK9 IDE once this is done: Put the caret on Hello, on line 9
Rewrite String ConcatenationStep 2: Rewrite String ConcatenationRight-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 ConcatenationStep 3: Preview and applyThe preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply.
Rewrite String ConcatenationThe resultThat 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 ConcatenationWhere this lesson comes fromThe 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 UpPull UpPull 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 UpStep 1: Where it isPut the caret on describe, on line 10. The EK9 IDE once this is done: Put the caret on describe, on line 10
Pull UpStep 2: Pull UpRight-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 UpStep 3: Preview and applyThe preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply.
Pull UpThe resultThat 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 UpWhere this lesson comes fromFor AI assistants - the MCP tool ek9_pull_up.
Push DownPush DownPush 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 DownStep 1: Where it isPut the caret on fly, on line 8. The EK9 IDE once this is done: Put the caret on fly, on line 8
Push DownStep 2: Push DownRight-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 DownStep 3: Preview and applyThe 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 DownThe resultThat 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 DownWhere this lesson comes fromFor AI assistants - the MCP tool ek9_push_down.
Extract TraitExtract TraitExtract 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 TraitStep 1: Where it isPut the caret on Product, on line 6. The EK9 IDE once this is done: Put the caret on Product, on line 6
Extract TraitStep 2: Extract TraitRight-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 TraitStep 3: Preview and applyThe 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 TraitThe resultThat 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 TraitWhere this lesson comes fromFor AI assistants - the MCP tool ek9_extract_trait.
Adopt TraitAdopt TraitAdopt 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 TraitStep 1: Right-click RobotRight-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 TraitStep 2: Name the trait, and OKGreeter 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 TraitThe resultThat 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 TraitWhere this lesson comes fromAnswers - ek9 -q and the IDE's Answers tab: 108, 210.For AI assistants - the MCP tool ek9_adopt_trait.
Make AbstractMake AbstractChange 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 AbstractStep 1: Where it isPut the caret on C7, on line 73. The EK9 IDE once this is done: Put the caret on C7, on line 73
Make AbstractStep 2: Make AbstractRight-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 AbstractStep 3: Preview and applyThe preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply.
Make AbstractThe resultThat 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 AbstractWhere this lesson comes fromThe 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 ClosedMake ClosedChange 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 ClosedStep 1: Where it isPut the caret on Shape, on line 6. The EK9 IDE once this is done: Put the caret on Shape, on line 6
Make ClosedStep 2: Make ClosedRight-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 ClosedStep 3: Preview and applyThe preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply.
Make ClosedThe resultThat 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 ClosedWhere this lesson comes fromAnswers - ek9 -q and the IDE's Answers tab: 574, 784.For AI assistants - the MCP tool ek9_make_closed.
Make ConcreteMake ConcreteChange 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 ConcreteStep 1: Where it isPut the caret on Shape, on line 6. The EK9 IDE once this is done: Put the caret on Shape, on line 6
Make ConcreteStep 2: Make ConcreteRight-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 ConcreteStep 3: Preview and applyThe preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply.
Make ConcreteThe resultThat 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 ConcreteWhere this lesson comes fromFor AI assistants - the MCP tool ek9_make_concrete.
Seal TypeSeal TypeChange 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 TypeStep 1: Where it isPut the caret on Shape, on line 6. The EK9 IDE once this is done: Put the caret on Shape, on line 6
Seal TypeStep 2: Seal TypeRight-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 TypeStep 3: Preview and applyThe 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 TypeThe resultThat 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 TypeWhere this lesson comes fromAnswers - ek9 -q and the IDE's Answers tab: 1171, 301, 608.For AI assistants - the MCP tool ek9_seal_type.
Unseal Type / Add to AllowlistUnseal Type / Add to AllowlistAdd 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 AllowlistStep 1: Add to AllowlistRight-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 AllowlistStep 2: Preview and applyThe 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 AllowlistStep 3: Unseal TypeRight-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 AllowlistStep 4: Preview and applyThe preview shows the allow only clause removed entirely; then the IDE formats the file. Choose Apply.
Unseal Type / Add to AllowlistThe resultThat 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 AllowlistWhere this lesson comes fromThe 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 FieldIntroduce FieldIntroduce 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 FieldStep 1: Where it isPut the caret on balance, on line 7. The EK9 IDE once this is done: Put the caret on balance, on line 7
Introduce FieldStep 2: Introduce FieldRight-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 FieldStep 3: Preview and applyThe preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply.
Introduce FieldThe resultThat 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 FieldWhere this lesson comes fromFor AI assistants - the MCP tool ek9_introduce_field.
Rename FieldRename FieldRename 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 FieldStep 1: Where it isPut the caret on farewell, on line 6. The EK9 IDE once this is done: Put the caret on farewell, on line 6
Rename FieldStep 2: Rename FieldRight-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 FieldStep 3: Preview and applyThe 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 FieldThe resultThat 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 FieldWhere this lesson comes fromFor AI assistants - the MCP tool ek9_rename_field.
Remove FieldRemove FieldRemove 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 FieldStep 1: Where it isPut the caret on spare, on line 7. The EK9 IDE once this is done: Put the caret on spare, on line 7
Remove FieldStep 2: Remove FieldRight-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 FieldStep 3: Preview and applyThe preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply.
Remove FieldThe resultThat 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 FieldWhere this lesson comes fromFor AI assistants - the MCP tool ek9_remove_field.
Change VisibilityChange VisibilityChange 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 VisibilityStep 1: Where it isPut the caret on decorate, on line 14. The EK9 IDE once this is done: Put the caret on decorate, on line 14
Change VisibilityStep 2: Change VisibilityRight-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 VisibilityStep 3: Preview and applyThe preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply.
Change VisibilityThe resultThat 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 VisibilityWhere this lesson comes fromFor AI assistants - the MCP tool ek9_change_visibility.
Surround WithSurround WithSurround 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 WithStep 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 WithThe resultThat 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 WithWhere this lesson comes fromFor AI assistants - the MCP tool ek9_surround_with.
Generate DelegationGenerate DelegationGenerate 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 DelegationStep 1: Where it isPut the caret on Robot, on line 17. The EK9 IDE once this is done: Put the caret on Robot, on line 17
Generate DelegationStep 2: Generate DelegationRight-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 DelegationStep 3: Preview and applyThe 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 DelegationThe resultThat 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 DelegationWhere this lesson comes fromFor AI assistants - the MCP tool ek9_generate_delegation.
Generate DispatcherGenerate DispatcherGenerate 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 DispatcherStep 1: Where it isPut the caret on AnimalDispatcher, on line 12. The EK9 IDE once this is done: Put the caret on AnimalDispatcher, on line 12
Generate DispatcherStep 2: Generate DispatcherRight-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 DispatcherStep 3: Preview and applyThe 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 DispatcherThe resultThat 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 DispatcherWhere this lesson comes fromFor AI assistants - the MCP tool ek9_generate_dispatcher.
Extract to Localized TextExtract to Localized TextExtract 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 TextStep 1: Where it isPut 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 TextStep 2: Extract to Localized TextRight-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 TextStep 3: Preview and applyThe 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 TextThe resultThat 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 TextWhere this lesson comes fromAnswers - ek9 -q and the IDE's Answers tab: 113.For AI assistants - the MCP tool ek9_extract_to_localized_text.
Organize Localized TextOrganize Localized TextOrganize 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 TextStep 1: Choose the layoutChoose Code > Localisation > Organize Localized Text… The EK9 IDE once this is done: Choose Code > Localisation > Organize Localized Text…
Organize Localized TextStep 2: Split by LocaleChoose Split by Locale. That is one file per language, the layout Getting Started's localisation chapter uses.
Organize Localized TextStep 3: Preview and applyThe 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 TextThe resultThat 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 TextWhere this lesson comes fromAnswers - ek9 -q and the IDE's Answers tab: 113, 1380.For AI assistants - the MCP tool ek9_organize_localized_text.
Inline CandidatesInline CandidatesThe 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 CandidatesStep 1: Open the windowChoose View > Tool Windows > Inline Candidates. The EK9 IDE once this is done: Choose View > Tool Windows > Inline Candidates
Inline CandidatesStep 2: The findingsheading 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 CandidatesStep 3: Inline oneRight-click heading and choose Inline variable… The EK9 IDE once this is done: Right-click heading and choose Inline variable…
Inline CandidatesStep 4: Preview and applyThe preview shows heading's value moved to where it was used, and the declaration gone. Choose Apply.
Inline CandidatesThe resultThat 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 CandidatesWhere this lesson comes fromFor AI assistants - the MCP tool ek9_find_inline_candidates, ek9_inline_variable.
Promote to ConstantPromote to ConstantPromote 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 ConstantStep 1: Where it isPut 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 ConstantStep 2: Promote to ConstantRight-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 ConstantStep 3: Preview and applyThe preview shows every change the refactoring makes; then the IDE formats each file it changed. Choose Apply.
Promote to ConstantThe resultThat 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 ConstantWhere this lesson comes fromAnswers - ek9 -q and the IDE's Answers tab: 140.For AI assistants - the MCP tool ek9_promote_to_constant.
Convert ConstructorConvert ConstructorConvert 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 ConstructorStep 1: The constructorPut 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 ConstructorStep 2: Expand itRight-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 ConstructorThe resultThat 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 ConstructorWhere this lesson comes fromFor AI assistants - the MCP tool ek9_convert_constructor.
Expand Default OperatorExpand Default OperatorExpand 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 OperatorStep 1: The default operatorPut the caret on the default operator $ line. The EK9 IDE once this is done: Put the caret on the default operator $ line
Expand Default OperatorStep 2: Expand itRight-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 OperatorThe resultThat 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 OperatorWhere this lesson comes fromFor AI assistants - the MCP tool ek9_expand_default_operator, ek9_collapse_to_default_operator.
Rename File / Move FileRename File / Move FileRename 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 FileStep 1: Rename itIn 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 FileStep 2: Move itIn 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 FileThe resultThat 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 FileWhere this lesson comes fromFor AI assistants - the MCP tool ek9_rename_file, ek9_move_file.
Toggle Comment, Remove Comment, ReformatToggle Comment, Remove Comment, ReformatToggle 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, ReformatStep 1: Toggle CommentPut 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, ReformatStep 2: Remove CommentRight-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, ReformatStep 3: Reformat FileA 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, ReformatStep 4: Reformat All Open Filesgreet.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, ReformatThe resultThat 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, ReformatWhere this lesson comes fromAnswers - 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 DirectoryNew EK9 File, New Directory, Delete File, Delete DirectoryThe 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 DirectoryStep 1: A new fileRight-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 DirectoryStep 2: A new directoryRight-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 DirectoryStep 3: Delete it againRight-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 DirectoryStep 4: Delete the old fileRight-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 DirectoryThe resultThat 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 DirectoryWhere this lesson comes fromFor AI assistants - the MCP tool ek9_write_file, ek9_delete_file, ek9_delete_directory.
The Journal: one runThe Journal: one runThe 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 runStep 1: A program that fails lateOrders 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 runStep 2: Record a runChoose 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 runStep 3: The storyA 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 runStep 4: Where it went wrongClick 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 runStep 5: The marks in the editorIn 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 runThe resultThat 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 runWhere this lesson comes fromFor AI assistants - the MCP tool ek9_debug_inspect.
The Journal: comparing runsThe Journal: comparing runsComparing 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 runsStep 1: A program with passing and failing runsOrders 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 runsStep 2: Record several runsChoose 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 runsStep 3: Choose two to compareClick 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 runsStep 4: What only the failing run didThe 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 runsStep 5: The Journal ReportChoose 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 runsThe resultThat 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 runsWhere this lesson comes fromFor AI assistants - the MCP tool ek9_debug_inspect.
The Journal: a new investigationThe Journal: a new investigationTrying 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 investigationStep 1: Orders, and its defectOrders 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 investigationStep 2: Record one failing runChoose 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 investigationStep 3: Try it again, one input changedRight-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 investigationStep 4: What changedBoth 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 investigationThe resultThat 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 investigationWhere this lesson comes fromFor AI assistants - the MCP tool ek9_debug_session.
Show Blast RadiusShow Blast RadiusShow 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 RadiusStep 1: Where the change startsPut 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 RadiusStep 2: Show Blast RadiusRight-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 RadiusStep 3: The rippleThe 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 RadiusStep 4: The other directionChoose 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 RadiusThe resultThat 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 RadiusWhere this lesson comes fromThe 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.
CapabilitiesCapabilitiesThe 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 ...
CapabilitiesStep 1: Open the windowChoose View > Tool Windows > Capabilities. The EK9 IDE once this is done: Choose View > Tool Windows > Capabilities
CapabilitiesStep 2: The auditStdout 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.
CapabilitiesStep 3: Add a capabilityRight-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
CapabilitiesStep 4: Preview and applyThe preview shows Stdout added to the capabilities list; then the IDE formats the file. Choose Apply.
CapabilitiesStep 5: Remove an unused capabilityRight-click TCP and choose Remove unused capability 'TCP'. The EK9 IDE once this is done: Right-click TCP and choose Remove unused capability 'TCP'
CapabilitiesStep 6: Preview and applyThe preview shows TCP removed from the capabilities list; then the IDE formats the file. Choose Apply.
CapabilitiesThe resultThat 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 ...
CapabilitiesWhere this lesson comes fromThe 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.