Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Syntax

Bop’s syntax is deliberately simple. If you’ve seen Python or a C-family language, most of it will look familiar — curly braces for blocks, # for comments, newlines (rather than semicolons) terminating statements.

Blocks

Code blocks use curly braces { } and only appear after control-flow or declaration keywords (if, else, while, for, repeat, fn, struct, enum, match):

if count > 3 {
  print("That's a lot!")
}

Important: The opening { must be on the same line as its keyword. Bop automatically inserts semicolons at the end of lines, so putting { on the next line would cause a parse error.

// Good
if count > 3 {
  print("Nice!")
}

// Bad — will cause an error
if count > 3
{
  print("Nice!")
}

Statements

Statements end with a newline. Bop automatically inserts semicolons after lines ending in:

  • An identifier or literal
  • true, false, none
  • break, continue, return
  • ), ], }

You can put multiple statements on one line with an explicit semicolon:

let x = 1; let y = 2

Comments

Line comments start with //. Everything after // on that line is ignored:

// This is a comment
let x = 5   // So is this

There is no block-comment syntax. # is not a comment leader — a stray # produces a lexer error.

Identifiers

Variable and function names start with a letter or underscore and can contain letters, digits, and underscores:

let my_var = 5
let _count = 0
let item3 = "hello"

Case conventions are enforced

Bop checks the shape of every declared name at parse time and rejects mismatches with a suggestion:

DeclarationRequired shapeExamples
let, fn, parameters, fields, aliases, for-loop vars, match bindingsstarts with a lowercase letter or _let x, fn double(n), for i in …
constALL_CAPS (+ digits / _)const PI = 3.14, const MAX_SIZE = 100
struct, enum, variant namesstarts with an uppercase letterstruct Point, enum Shape { Circle, Rect }

Single-letter types like enum Dir { N, E, S, W } are fine — the rule is “starts with an uppercase letter”, not “must have a lowercase character somewhere.”

A leading underscore (_foo, _Internal, _DEBUG) marks a name as “private by convention” — glob use imports skip them. The wildcard _ on its own is used in let _ = foo() (explicitly ignore) and in patterns (match anything).

Whitespace

Spaces and tabs are insignificant — use whatever indentation style you like. Only newlines matter (they end statements).

Keywords

These words are reserved and can’t be used as identifiers:

let const fn return
if else while for in repeat break continue
use as struct enum match try
true false none

There are no word-spelled logical operators — use &&, ||, ! rather than and, or, not.