Early preview: syntax, standard library APIs, and tooling may change.

Working ProgramsBuilding a Small CLI App

Building a Small CLI App

Keep parsing and I/O at the edge, with a pure core that is easy to test.

Argparse

std/argparse provides a Cli record plus flag, option, parse, and accessor helpers. Pass full args; parse skips the first element (the program entry).

cli: Cli = {
	name = "app",
	version = "0.1",
	description = "demo",
	params = []
}

Pure Core

Put deterministic word-count logic in pure functions.

pure func count_words(text: String) -> Int:
	text
		.words()
		.length()

Impure Shell

Read files, parse args, and print in main.

func main(args: List[String]) -> Int:
	print(count_words("one two"))
	0

Tests

Test the pure core without invoking the CLI.

func test_count_words() -> Bool:
	count_words("one two") == 2

Example

wordcount.brp
import:
	argparse:
		Cli,
		ArgumentParseOutcome(ArgumentsParsed, ArgumentsHelpRequested, ArgumentsVersionRequested, ArgumentsParseFailed),
		arg_int,
		format_error,
		get_int_or,
		parse,
	io: read_line


pure func count_words(text: String, min_len: Int) -> Int:
	var count: Int = 0

	for word in text.words():
		if word.length() >= min_len:
			count += 1

	count


func main(args: List[String]) -> Int:
	cli: Cli = {
		name = "wordcount",
		version = "0.1",
		description = "count words",
		params = [
			arg_int("min-length", Some("--min-length"), Some("-m"), "minimum length", Some("N")),
		]
	}

	match parse(cli, args):
		ArgumentsParsed(parsed):
			min_len: Int = get_int_or(parsed, "min-length", 1)
			var total: Int = 0
			while True:
				match read_line():
					Some(line): total += count_words(line, min_len)
					None: break
			print(total)
			0
		ArgumentsParseFailed(err):
			print_error(format_error(err))
			1
		ArgumentsHelpRequested(text):
			print(text)
			0
		ArgumentsVersionRequested(text):
			print(text)
			0

Try it

terminal
printf 'one three seven\n' | blorp run examples/docs/working-programs/building-a-small-cli-app/wordcount.brp -- --min-length 4