Heroes / Guide / chapter 1

A first program

A file and a main function are enough to get started.

Your first Heroes program needs one file with a main function. You do not need a project file or an imported library to print a result.

The whole program

function main()
    print((2 + 3) * 4)
examples/gallery/00-first.hero, lines 7–8
$ heroes run examples/gallery/00-first.hero
20

function main() defines where the program starts. It takes no arguments and returns no value, so there is no return type after the parentheses. A function that returns an integer declares it with -> i64. print is built in: it prints its arguments one after another, then starts a new line.

What is not in that file

The file contains only the code the program needs. These rules reduce how much information you need to look up elsewhere:

The indentation is the structure

Indent each block by four spaces relative to the line that opens it. The rule applies at every level. A different indentation produces this error:

$ heroes check hello.hero
error[indentation_not_multiple_of_4]: indentation must be exactly 4 spaces per level; found 2
  at hello.hero:2:1
    |
  2 |   print("hi")
    | ^^

Tabs produce a separate error. Consistent indentation makes versions of a file easier to compare. heroes fmt prints code in the language’s standard format. Files already in that format remain unchanged, byte for byte.

The rule is older than it looks. Python did not invent it: it took it from ABC, a teaching language from the same lab, and Guido van Rossum says so himself in Python’s own documentation, calling ABC the origin of many Python features, including the use of indentation for statement grouping. Heroes takes the same idea and makes it stricter, because a rule with one spelling is a rule a model cannot get subtly wrong: exactly four spaces, never a tab.

Comments are where the documentation lives

Write documentation in comments. # starts a comment that ends at the end of the line. Comments may contain Markdown, a text format for headings, lists and other elements. ## opens a section:

## Points
#
# Records, their constructors, and UFCS. Every field is named at the call
# site, always — `Point(3, 4)` does not exist.
examples/gallery/01-points.hero, lines 1–4

A comment directly above a declaration documents it, with no extra markers:

# A position on the integer grid.
record Point
    x: i64
    y: i64
examples/gallery/01-points.hero, lines 6–9

One file is one module

When you need more than one file, organize them into modules. use makes another module available:

use eval
examples/calculator/main.hero, line 31

This line associates the name eval with eval.hero in the same directory. Prefix a function with that name to use it: eval.calculate(text, env). Each module needs its own use line; there is no wildcard import to bring in all its names at once. You can rename a module with as, as chapter 12 shows. The prefix and the use line tell you which file to consult.

The verbs

The heroes command provides these subcommands, each with a specific task:

$ heroes check program.hero    # names and types, no binary
$ heroes run program.hero      # compile and execute
$ heroes build program.hero    # compile only
$ heroes test program.hero     # run the file's tests
$ heroes fmt program.hero      # print the canonical form

Tests are part of the language. The points file shown above contains two:

$ heroes test examples/gallery/01-points.hero
ok   "the 3-4-5 triangle"
ok   "a rectangle keeps its size when it moves"
2 tests, all passed

Next: Errors, learn how to group data and name arguments in calls. Back to the chapter list.

Run a program of your own: it takes four commands. Or take the whole language in one file, and every program already written in it.