Your first small CLI app
Docs contents · Previous: Setup and first run · Next: Learn by writing code
Build a CLI app that checks whether an amount is at most 1,000 yen. Install a released Nagi compiler, Rust/Cargo, and C build tools. Follow setup first if you have not prepared them.
This example reads one line and prints a result. It does not save data to a file or database. Before adding persistence, read the current API and limits in SQLite.
On this page
1. Create a working folder and file
Choose a location in your terminal. Create a folder named nagi-budget and make it the current directory:
mkdir nagi-budget
cd nagi-budget
Create first_app.nagi in this folder and save the following code. The same code is in the runnable repository example.
def within_budget(amount_text: view[str], limit: i64) -> Result[bool, Error]:
amount = try parse_i64(amount_text)
if amount < 0:
return error("amount must be non-negative")
return ok(amount <= limit)
def main() -> Result[unit, Error]:
print("Enter a whole-number amount:")
text = try read_line()
fits = try within_budget(view(text), 1000)
if fits:
print("within budget")
else:
print("over budget")
return ok(print("done"))
When mkdir and cd succeed, they print nothing. Confirm that the editor saved the file as nagi-budget/first_app.nagi. If the folder already exists, skip mkdir and move into it.
within_budget converts the input string to an integer. view[str] borrows the string for reading, and parse_i64 returns a Result[i64, Error]. try propagates failure to the caller. After rejecting negative amounts, the function returns the comparison inside ok. main also uses try, so its return type is Result.
For these first terms, see views and ownership and Result, try, and match. unit is the type for a computation with no useful value; here, print returns it inside ok(...).
2. Check and run it
From the same working folder, check the compiler version and source:
nagic --version
nagic check first_app.nagi
For Nagi 0.1.11, the version command prints nagic 0.1.11. A successful check exits with code 0 and reports no Nagi syntax, type, or ownership diagnostics. check does not run the Rust/Cargo build.
On success, it prints checked followed by the path to the checked file. If it fails, inspect the source line, confirm nagic --version is 0.1.11 or later, and check that first_app.nagi was saved in the working folder.
On Linux and macOS, pipe an amount into the app:
printf '700\n' | nagic run first_app.nagi
In PowerShell, run the same check with:
"700" | nagic run .\first_app.nagi
The app's standard output is:
Enter a whole-number amount:
within budget
done
run builds and executes the app through Rust/Cargo. Even after check succeeds, the app can fail before execution if a C compiler or linker is missing, or if a dependency cannot be downloaded. See build tools and check versus build.
3. Try boundary values and fix a mistake
To observe the mistake, temporarily change return ok(amount <= limit) in within_budget to return ok(amount < limit) and save the file. From the working folder, check it and enter the amount equal to the limit, 1000:
nagic check first_app.nagi
printf '1000\n' | nagic run first_app.nagi
nagic check .\first_app.nagi
"1000" | nagic run .\first_app.nagi
With <, the result line is over budget. To accept an amount equal to the limit, change the comparison back to amount <= limit, save it, run nagic check first_app.nagi again, and verify the fix with these three inputs:
| Input | Expected output | What it checks |
|---|---|---|
700 |
within budget |
Below the limit |
1000 |
within budget |
Equal to the limit |
1001 |
over budget |
Above the limit |
If 1000 prints over budget, change the comparison to amount <= limit. Run nagic check first_app.nagi again and compare all three inputs with the table.
On Linux and macOS, run these three commands. In PowerShell, use the corresponding commands below.
printf '%s\n' '700' | nagic run first_app.nagi
printf '%s\n' '1000' | nagic run first_app.nagi
printf '%s\n' '1001' | nagic run first_app.nagi
"700" | nagic run .\first_app.nagi
"1000" | nagic run .\first_app.nagi
"1001" | nagic run .\first_app.nagi
Each command prints the prompt, the result in the table, and done. abc fails number conversion; -1 returns the app's own error. Both exit with status 1. The following table shows runtime errors printed by the started app, not compiler diagnostics. Nagi 0.1.11 prints:
| Input | Error output | Exit code |
|---|---|---|
abc |
Invalid: invalid digit found in string |
1 |
-1 |
Invalid: amount must be non-negative |
1 |
On Linux/macOS, pipe printf '%s\n' 'abc' or printf '%s\n' '-1' into nagic run first_app.nagi; in PowerShell, pipe "abc" or "-1" the same way. If a runtime error is shown, see propagating and recovering from Result. If the compiler or Cargo reports an error before the app starts, check the build tools and check versus build.
A negative amount returns the Error created by the app; abc returns the Error from parse_i64. try propagates both to main. See Results and error handling to recover from a failure locally.
Nagi does not currently provide a built-in unit test framework. This tutorial uses a small input table that you run and compare manually. For automated regression tests when changing the compiler, see the contribution guide and compiler test guide.
4. Extend the example
Continue with the language guide and language feature index for functions, Lists, classes, loops, enums, nullable values, Result, and match. Read imports and modules to split files, ownership and borrowing to pass values, and Rust integration to call a Rust library.