Programming Neam
📖 18 min read

Chapter 3: Hello World -- Your First Neam Program #

"The beginning is the most important part of the work." -- Plato

Every programming language journey starts the same way: with a program that says hello. In this chapter, you will write, compile, and run your first Neam program. Along the way, you will learn how the Neam toolchain works -- from source code to bytecode to execution -- and pick up the fundamental building blocks you will use in every program you write.

By the end of this chapter, you will be able to:


3.1 Creating Your First .neam File #

Open your text editor of choice and create a new file called hello.neam. Type the following program exactly as shown:

neam
{
  emit "Hello, World!";
}

Save the file. That is it -- three lines, and you have a complete Neam program.

Before diving into what each piece does, let us get it running so you can see the result immediately.


3.2 The Compile-Run Cycle #

Neam uses a two-step execution model. You do not run source code directly. Instead, you first compile your .neam source file into a .neamb bytecode file, then you execute that bytecode on the Neam virtual machine (VM).

hello.neam
(source code)
hello.neamb
(bytecode)
Terminal
Output

This two-step model gives Neam several advantages:

  1. Faster execution. The VM runs pre-compiled bytecode, not raw text. The parser and compiler do their work once, up front.
  2. Early error detection. Syntax errors and some semantic errors are caught at compile time, before your program ever runs. This includes agent-specific checks like verifying that handoff targets exist and tool schemas are valid -- errors that Python frameworks can only discover at runtime.
  3. Portable bytecode. A .neamb file can be distributed and run on any machine that has the Neam VM installed, without sharing your source code.
  4. Minimal startup time. Loading pre-compiled bytecode takes approximately 9 milliseconds, compared to 2,800 milliseconds for importing a Python AI framework. This difference matters in serverless deployments where every cold start costs money.

Why Compilation Matters for AI Agents #

If you come from a Python background, you might wonder why a compiled step is necessary. After all, Python's interpreted model works well for most AI development. The answer becomes clear when you consider what happens in production.

An AI agent system is not just code -- it is a topology. Agents hand off to other agents. Tools have parameter schemas that must match function signatures. Knowledge bases must exist before agents reference them. Guardrails must be attached to the right agents. In Python, all of these connections are validated at runtime, which means the first time you discover a broken handoff might be when a customer triggers that particular path at 3 AM.

Neam's compiler validates the entire topology before a single line of code runs. If agent Triage hands off to agent Billing, the compiler verifies that Billing exists and accepts the right input. If a tool declares a query parameter of type string, the compiler checks that the schema is well-formed. This is not just convenience -- it is a fundamental safety property for production AI systems.

Comparing the Two Approaches #

Consider the difference for a simple agent program:

Python approach (interpreted):

Write code
Run
Discover errors at runtime
Fix
Run again

Neam approach (compiled):

Write code
Compile (errors caught here)
Run (confidence that topology is valid)

The compilation step adds a few milliseconds to your workflow but saves hours of debugging in production.

Compiling #

Open your terminal, navigate to the directory where you saved hello.neam, and run:

bash
neamc hello.neam -o hello.neamb

If the compilation succeeds, you will see no output -- silence means success. A new file called hello.neamb will appear in the same directory.

If you made a typo, the compiler will report an error with a line number. Fix the error in your source file and compile again.

Running #

Now execute the compiled bytecode:

bash
neam hello.neamb

You should see:

text
Hello, World!

Congratulations -- you have just run your first Neam program.


3.3 The emit Statement #

The emit statement is Neam's primary output mechanism. It sends a value to the output stream -- in a terminal, that means printing text to your screen.

neam
emit "Hello, World!";

A few things to notice:

You can emit any value, not just strings:

neam
{
  emit "A string";
  emit 42;
  emit 3.14;
  emit true;
  emit nil;
}

Expected output:

text
A string
42
3.14
true
nil

3.4 The Main Execution Block #

Every Neam program needs an entry point -- a place where execution begins. In Neam, this is the main execution block, written as a pair of curly braces:

neam
{
  // Your code goes here
}

The main block is the top-level { ... } in your file. When the VM loads your bytecode, it begins executing the instructions inside this block, in order, from top to bottom.

Think of the main block as the main() function in C or Java, except that Neam uses a more concise syntax.

Important rules about the main block:

Here is a program with multiple statements:

neam
{
  emit "Line 1: Starting the program";
  emit "Line 2: Doing some work";
  emit "Line 3: All done";
}

Expected output:

text
Line 1: Starting the program
Line 2: Doing some work
Line 3: All done

3.5 The REPL: Interactive Exploration with neam-cli #

Sometimes you want to try things out quickly without creating a file, compiling, and running. For that, Neam provides an interactive Read-Eval-Print Loop (REPL) through the neam-cli tool.

Starting the REPL #

bash
neam-cli

You will see a prompt where you can type Neam expressions and statements:

text
Neam REPL v0.7.2
Type expressions or statements. Press Ctrl+D to exit.

neam> emit "Hello from the REPL!";
Hello from the REPL!

neam> emit 2 + 3;
5

neam> let name = "Neam";
neam> emit "Welcome to " + name;
Welcome to Neam

neam> emit f"Welcome to {name}!";
Welcome to Neam!

Running a File with neam-cli #

You can also use neam-cli to run a .neam source file directly, without manually compiling first:

bash
neam-cli hello.neam

This compiles and runs the file in one step -- convenient for development.

Watch Mode #

For rapid iteration during development, use watch mode:

bash
neam-cli --watch hello.neam

In watch mode, neam-cli monitors your source file for changes and automatically recompiles and reruns the program every time you save. This gives you an experience similar to live-reloading in web development.

Experimenting with Types in the REPL #

The REPL is an excellent place to explore how Neam handles different value types:

text
neam> emit typeof(42);
number

neam> emit typeof("hello");
string

neam> emit typeof(true);
boolean

neam> emit typeof(nil);
nil

neam> emit typeof([1, 2, 3]);
list

neam> emit typeof({"key": "value"});
map

You can also test arithmetic, string operations, and even define functions:

text
neam> let x = 10;
neam> let y = 3;
neam> emit str(x * y + 2);
32

neam> emit "Neam".upper();
NEAM

neam> emit str(len("Hello, World!"));
13
💡 Tip

The REPL maintains state across lines within a session. Variables you define on one line are available on subsequent lines. This makes it ideal for building up expressions step by step.

The Development Workflow #

In practice, most Neam development follows a cycle:

  1. Explore in the REPL to test ideas and understand behavior.
  2. Write your program in a .neam file.
  3. Develop using neam-cli --watch for rapid iteration.
  4. Build with neamc when you are ready to deploy or distribute.

This workflow gives you the best of both worlds: the interactive exploration of an interpreted language with the safety and performance of a compiled one.

When to Use Each Tool #

Tool Use Case
neamc + neam Production builds, CI/CD, distributing bytecode
neam-cli file.neam Quick development runs
neam-cli --watch Iterative development with auto-reload
neam-cli (no args) Interactive exploration, testing snippets

3.6 Understanding Bytecode: What .neamb Contains #

When you compile a .neam source file, the compiler produces a .neamb binary file. This is not machine code (like a C compiler produces). It is bytecode -- a compact, platform-independent representation of your program designed to be executed by the Neam virtual machine.

The Compilation Pipeline #

Under the hood, neamc performs several stages:

Source
(.neam)
Parser
(lexer +
parser)
AST
(Abstract
Syntax
Tree)
Compiler
(code gen)
.neamb
bytecode
  1. Lexing. The source text is broken into tokens: keywords (emit), strings ("Hello"), symbols ({, }, ;), and so on.
  2. Parsing. Tokens are assembled into an Abstract Syntax Tree (AST) -- a structured representation of your program's logic.
  3. Compilation. The AST is walked and translated into a sequence of bytecode instructions (opcodes) plus a constant pool.

Inside a .neamb File #

A .neamb file has a binary format with the following structure:

Section Description
Magic bytes NEAM (4 bytes) -- identifies the file as Neam bytecode
Version Format version number
Manifest JSON metadata about the program
Constants Pool of constant values (strings, numbers) used in the program
Code Sequence of bytecode instructions (opcodes + operands)
Source map Mapping from bytecode offsets to source line numbers

For our hello.neam program, the bytecode would contain approximately:

  1. A constant entry for the string "Hello, World!"
  2. An OP_CONST instruction to push that string onto the stack
  3. An OP_EMIT instruction to output the value on top of the stack

You do not need to understand bytecode to use Neam effectively, but knowing it exists helps you understand error messages, performance characteristics, and the overall architecture of the language.


3.7 Comments #

Comments are text in your source code that the compiler ignores. They exist purely for humans -- to explain what code does, to leave notes for your future self, or to temporarily disable a line of code.

Neam supports four comment styles:

Single-Line Comments: // #

neam
// This is a single-line comment
emit "Hello";  // This comment is at the end of a line

Everything from // to the end of the line is ignored by the compiler.

Multi-Line Comments: / / #

neam
/* This is a multi-line comment.
   It can span multiple lines.
   Very useful for longer explanations. */
emit "Hello";

Multi-line comments begin with /* and end with */. Everything between those delimiters is ignored.

Documentation Comments: /// #

neam
/// Computes the sum of two numbers.
/// Returns the result as a Number.
fun add(a, b) {
  return a + b;
}

Triple-slash comments are documentation comments. They work like // but signal that the comment is meant to document the function or declaration that follows. Tools like neam-lsp (the language server) can use these to provide hover documentation in your editor.

Block Documentation Comments: /* / #

neam
/**
 * Greets the user by name.
 *
 * Parameters:
 *   name - The name to greet
 *
 * Returns:
 *   A greeting string
 */
fun greet(name) {
  return "Hello, " + name + "!";
}

Block documentation comments work like /* */ but are specifically for multi-line documentation. The leading * on each line is a convention for readability, not a requirement.

Comment Best Practices #


3.8 String Basics and Concatenation #

Strings are sequences of characters enclosed in double quotes. You have already seen them in emit "Hello, World!". Let us explore a few more things you can do with strings.

String Literals #

neam
{
  emit "Hello, World!";
  emit "Neam is an agentic AI language.";
  emit "";  // An empty string
}

String Concatenation with + #

You can join two strings together using the + operator:

neam
{
  let greeting = "Hello";
  let name = "Neam";
  let message = greeting + ", " + name + "!";
  emit message;
}

Expected output:

text
Hello, Neam!

The + operator, when used with strings, concatenates (joins) them end to end. You can chain as many + operations as you need.

Mixing Strings and Numbers with str() #

In earlier versions of Neam (before v0.7.0), you could not directly concatenate a string and a number. Starting with v0.7.0, type coercion rules allow String + Number to work automatically. However, using str() remains good practice for clarity, especially in complex expressions:

neam
{
  let x = 42;
  emit "The answer is " + str(x);
}

Expected output:

text
The answer is 42

The str() function converts any value to its string representation:

neam
{
  emit str(42);       // "42"
  emit str(3.14);     // "3.14"
  emit str(true);     // "true"
  emit str(nil);      // "nil"
}

You will learn more about strings and their methods in Chapter 4.

F-Strings: Formatted String Literals #

Starting with Neam v0.7.0, you can use f-strings (formatted string literals) as a cleaner alternative to string concatenation. An f-string is a string prefixed with f that allows you to embed expressions directly inside curly braces {...}:

neam
{
  let name = "Neam";
  emit f"Hello, {name}!";
}

Expected output:

text
Hello, Neam!

The expression inside {...} is evaluated at runtime and its result is interpolated into the string. This works with any expression -- variables, arithmetic, function calls, and more:

neam
{
  // Arithmetic inside f-strings
  emit f"Result: {1 + 2}";         // Result: 3

  // Multiple interpolations in one string
  let lang = "Neam";
  let version = "0.7.2";
  emit f"{lang} v{version}";       // Neam v0.7.2

  // No need for str() -- f-strings handle conversion automatically
  let year = 2026;
  emit f"Year: {year}";            // Year: 2026
}

F-Strings vs. Concatenation #

Compare the two approaches for building the same string:

neam
{
  let greeting = "Hello";
  let name = "Neam";

  // Concatenation (what you already know)
  emit greeting + ", " + name + "!";

  // F-string (cleaner, easier to read)
  emit f"{greeting}, {name}!";
}

Both produce the same output: Hello, Neam!. F-strings are generally preferred for readability, especially when combining multiple values. You do not need str() inside an f-string -- non-string values are converted automatically.

Here is the earlier str() example rewritten with an f-string:

neam
{
  let x = 42;

  // With concatenation (requires str())
  emit "The answer is " + str(x);

  // With f-string (no str() needed)
  emit f"The answer is {x}";
}
📝 Note

F-strings were introduced in v0.7.0 as part of the DataFlow release. They are fully supported and safe to use in production code.

Escape Sequences #

Neam strings support standard escape sequences for special characters:

Escape Meaning
\" Double quote inside a string
\\ Literal backslash
\n Newline
\t Tab
neam
{
  emit "She said \"Hello!\"";
  emit "First line\nSecond line";
  emit "Column A\tColumn B";
}

String Length with len() #

The len() function returns the number of characters in a string:

neam
{
  let name = "Neam";
  emit "Name: " + name;
  emit "Length: " + str(len(name));   // Length: 4

  let empty = "";
  emit "Empty length: " + str(len(empty));   // Empty length: 0
}

len() also works on lists and maps, as you will see in Chapter 7.


3.9 Built-in Functions: A Preview #

Neam ships with over 80 built-in functions across 16 categories, all available in every program without any imports. You have already seen two of them: str() and len(). Here is a preview of the most commonly used ones. Each will be covered in detail in the relevant chapter.

Core Utility Functions #

Function Purpose Example Result
str(x) Convert any value to a string str(42) "42"
len(x) Length of string, list, or map len("hello") 5
typeof(x) Get the type name of a value typeof(42) "number"
input() Read a line from the user let name = input(); User-typed text
clock() Current time in seconds let t = clock(); 1706745600.0

Math Functions #

Function Purpose Example Result
math_abs(x) Absolute value math_abs(-7) 7
math_floor(x) Round down math_floor(3.7) 3
math_ceil(x) Round up math_ceil(3.2) 4
math_round(x) Round to nearest math_round(3.5) 4
math_sqrt(x) Square root math_sqrt(16) 4
math_min(a, b) Smaller of two math_min(3, 7) 3
math_max(a, b) Larger of two math_max(3, 7) 7
math_random() Random number 0–1 math_random() 0.7281...

String Methods #

Method Purpose Example Result
.len() Length of the string "hello".len() 5
.contains(sub) Check for substring "hello".contains("ell") true
.upper() Uppercase "hello".upper() "HELLO"
.lower() Lowercase "HELLO".lower() "hello"
.reverse() Reverse the string "hello".reverse() "olleh"
.words() Split into word list "hello world".words() ["hello", "world"]
.substring(s, e) Extract portion "hello".substring(0, 3) "hel"

Neam also supports string slicing with bracket syntax, which provides a concise alternative to .substring():

neam
{
  let s = "Hello, World!";
  emit s[0:5];     // "Hello"
  emit s[7:12];    // "World"
}

String slicing uses the syntax str[start:end], where start is inclusive and end is exclusive. You will explore slicing in more detail in Chapter 4.

You do not need to memorize these now. They are listed here so you know what is available as you work through the examples in this book. Appendix A provides the complete reference.


3.10 A First Look at For-Loops #

So far, every program you have written runs each statement exactly once, top to bottom. But one of the most powerful ideas in programming is repetition -- doing something multiple times without writing duplicate code. Neam provides the for loop for exactly this purpose.

This is just a brief introduction. Chapter 6 covers control flow in full detail, including if, while, for, and more. Here, you will see just enough to start experimenting.

Iterating Over a List #

The simplest form of a for-loop iterates over each item in a list:

neam
{
  let colors = ["red", "green", "blue"];
  for color in colors {
    emit f"Color: {color}";
  }
}

Expected output:

text
Color: red
Color: green
Color: blue

The loop variable color takes on each value from the list in order. The body (the code between { and }) runs once for each item.

Counting with range() #

When you need to repeat something a specific number of times, use range():

neam
{
  for i in range(5) {
    emit f"Count: {i}";
  }
}

Expected output:

text
Count: 0
Count: 1
Count: 2
Count: 3
Count: 4

range(n) generates a sequence of numbers from 0 to n - 1. Combined with a for-loop, it gives you a simple counting mechanism.

A Practical Example #

Here is a small program that combines variables, f-strings, and a for-loop:

neam
{
  let languages = ["Neam", "Python", "Rust"];
  emit "Languages I am learning:";
  for lang in languages {
    emit f"  - {lang}";
  }
  emit f"Total: {languages.len()}";
}

Expected output:

text
Languages I am learning:
  - Neam
  - Python
  - Rust
Total: 3
📝 Note

Full control flow details -- including if/else, while loops, break, continue, and loop expressions -- are covered in Chapter 6. For now, the for loop gives you a tool for exploring lists and repeating actions.


3.11 Your First Complete Program #

Let us put everything together. Create a file called welcome.neam:

neam
{
  // Greet the user
  emit "=================================";
  emit "  Welcome to the Neam Language!  ";
  emit "=================================";
  emit "";

  // Show some basic information
  let language = "Neam";
  let version = "0.7.2";
  let purpose = "Agentic AI Programming";

  emit "Language: " + language;
  emit "Version:  " + version;
  emit "Purpose:  " + purpose;
  emit "";

  // Demonstrate string concatenation
  let full_description = language + " v" + version + " - " + purpose;
  emit "Full description: " + full_description;
  emit "";

  // The same line using an f-string (cleaner alternative)
  emit f"Full description: {language} v{version} - {purpose}";
  emit "";

  // Demonstrate numeric output
  let year = 2026;
  emit "Year: " + str(year);
  emit f"Year: {year}";  // f-string version -- no str() needed
  emit "";

  /* Multi-line comment:
     This program demonstrates:
     - The emit statement
     - String variables and concatenation
     - The str() conversion function
     - All four comment styles
  */

  /// Final farewell message
  emit "Happy coding!";
}

Step-by-Step Walkthrough #

  1. Compile the program:
bash
neamc welcome.neam -o welcome.neamb
  1. Run the compiled bytecode:
bash
neam welcome.neamb
  1. Expected output:
text
=================================
  Welcome to the Neam Language!
=================================

Language: Neam
Version:  0.7.2
Purpose:  Agentic AI Programming

Full description: Neam v0.7.2 - Agentic AI Programming

Full description: Neam v0.7.2 - Agentic AI Programming

Year: 2026
Year: 2026

Happy coding!

Walking Through the Execution #

Let us trace through the program line by line:

Line Code What Happens
7 emit "====..."; Pushes the string constant, emits it
8 emit " Welcome..."; Same -- pushes and emits
9 emit "====..."; Same
10 emit ""; Emits an empty line
13 let language = "Neam"; Declares variable, stores "Neam"
14 let version = "0.6.5"; Declares variable, stores "0.6.5"
15 let purpose = "Agentic AI..."; Declares variable, stores the string
17 emit "Language: " + language; Concatenates and emits "Language: Neam"
18 emit "Version: " + version; Concatenates and emits "Version: 0.7.2"
19 emit "Purpose: " + purpose; Concatenates and emits the purpose
22 let full_description = ...; Concatenates all parts into one string
23 emit "Full description: " + ...; Emits the combined string
26 emit f"Full description: ..."; F-string version -- same output, cleaner syntax
29 let year = 2026; Stores the number 2026
30 emit "Year: " + str(year); Converts 2026 to "2026", concatenates, emits
31 emit f"Year: {year}"; F-string version -- auto-converts the number
41 emit "Happy coding!"; Final emit

Notice how execution flows top to bottom, one statement at a time. There are no branches, no function calls -- just sequential execution. (You got a taste of loops in Section 3.10, and you will explore the full set of control flow constructs in Chapter 6.)


3.12 A First Glimpse of Agents #

Everything you have learned so far -- emit, variables, strings, the compile-run cycle -- applies to all Neam programs. But Neam was designed for one purpose above all others: building AI agents. Let us take a brief look at what that looks like, even though agents are not covered in detail until Chapter 10.

Here is a complete Neam program that creates an AI agent and asks it a question:

neam
agent Assistant {
  provider: "ollama",
  model: "llama3",
  temperature: 0.7,
  system: "You are a helpful assistant. Answer concisely."
}

{
  let question = "What is the capital of France?";
  emit f"Question: {question}";

  let answer = Assistant.ask(question);
  emit f"Answer: {answer}";
}

Notice the structure:

This is the core insight of Neam's design: agents are language constructs, not library calls. You do not import a framework, instantiate a client object, configure an HTTP session, and parse a JSON response. You declare an agent and call .ask(). The language handles everything else.

Agents, tools, handoffs, knowledge bases, and multi-agent orchestration are explored in depth starting in Part III. For now, just remember: everything you learn about variables, functions, and control flow in Parts I and II applies directly when you start building agent systems.


3.13 From Python to Neam: A Conceptual Bridge #

If you are coming from Python -- and many readers will be, given Python's dominance in AI -- the following table maps familiar Python concepts to their Neam equivalents:

Python Neam Key Difference
print("hello") emit "hello"; emit is a keyword, not a function
x = 42 let x = 42; Explicit let declaration required
f"Hello, {name}" f"Hello, {name}" Same syntax!
for x in items: for x in items { ... } Braces instead of colon + indent
# comment // comment C-style comment syntax
"""docstring""" /// docstring or /** ... */ Documentation comments
if __name__ == "__main__": { ... } Main block is the entry point
python script.py neamc script.neam -o s.neamb && neam s.neamb Compile-then-run
from langchain import ... agent Bot { ... } Agents are built into the language
str(42) str(42) Same!
len("hello") len("hello") Same!
type(x).__name__ typeof(x) Simpler syntax

Some things feel familiar. Others are deliberately different. The key mental shift is this: in Python, AI capabilities are things you import from a library. In Neam, AI capabilities are part of the language itself. You do not configure an LLM client -- you declare an agent. You do not write a tool wrapper function -- you declare a tool with a schema. You do not manage handoff logic in your own code -- you declare handoff targets on the agent.

This shift from "AI as a library" to "AI as a language construct" is the fundamental idea behind Neam.


3.14 Common Mistakes and How to Fix Them #

As you start writing Neam code, you will inevitably hit a few common errors. Here is a quick reference:

Missing Semicolon #

neam
// WRONG
{
  emit "Hello"
}

Error: Expected ';' after expression.

Fix: Add a semicolon after every statement.

neam
// CORRECT
{
  emit "Hello";
}

Missing Main Block #

neam
// WRONG
emit "Hello";

Error: Unexpected token 'emit'.

Fix: Wrap your statements in a main execution block.

neam
// CORRECT
{
  emit "Hello";
}

Mismatched Quotes #

neam
// WRONG
{
  emit "Hello, World!;
}

Error: Unterminated string.

Fix: Make sure every opening " has a matching closing ".

Relying on Implicit String + Number Coercion #

neam
// WORKS (since v0.7.0) but unclear intent
{
  emit "Count: " + 42;    // "Count: 42" -- auto-coerced
}

This compiles and runs correctly since v0.7.0 (String + Number auto-converts the number to a string). However, explicit conversion with str() is recommended for clarity, especially in complex expressions:

neam
// RECOMMENDED -- intent is clear
{
  emit "Count: " + str(42);
}

3.15 Chapter Summary #

In this chapter, you learned the foundational workflow for every Neam program:

You now have all the tools you need to write, build, and run simple programs. In the next chapter, you will learn about variables, data types, and operators -- including Neam's full numeric types, booleans, lists, maps, and deeper coverage of f-strings and string methods -- the building blocks for expressing logic in Neam.


Exercises #

Exercise 3.1: Hello, You Write a program that emits your name in a greeting. For example, if your name is Alice, the output should be:

text
Hello, Alice!
Welcome to the world of Neam.

Exercise 3.2: The Compile Cycle Create a file called info.neam that emits three lines: your name, your favorite programming language (before Neam!), and the current year. Compile it with neamc and run it with neam. Write down the exact commands you used.

Exercise 3.3: String Assembly Write a program that stores a first name and a last name in separate variables, then concatenates them into a full name with a space in between, and emits the result.

Exercise 3.4: Comment Styles Write a program that uses all four comment styles (//, /* */, ///, /** */) and emits at least two lines of output. Verify that none of the comments appear in the output.

Exercise 3.5: Number to String Write a program that stores the numbers 10, 20, and 30 in three variables, computes their sum, and emits the result as part of a sentence like: "The sum of 10, 20, and 30 is 60". You will need str().

Exercise 3.6: REPL Exploration Start neam-cli in REPL mode (no arguments). Try the following and record the output of each:

  1. emit "Neam";
  2. emit 100 + 200;
  3. let x = "hello"; emit x;

Exercise 3.7: Bytecode Investigation Compile a simple program and examine the .neamb file. Use a hex editor or the command xxd hello.neamb | head -5 on macOS/Linux. Can you find the NEAM magic bytes at the start of the file? What do the first four bytes look like in hex?

Exercise 3.8: F-String Rewrite Take the program from Exercise 3.5 (the one that computes the sum of three numbers) and rewrite all of the emit statements to use f-strings instead of concatenation with str(). Verify that the output is identical.

Exercise 3.9: For-Loop Countdown Write a program that uses a for loop with range(5) to emit a countdown from 5 to 1, followed by "Launch!". Hint: you can compute 5 - i inside the loop body.

Exercise 3.10: Error Practice Deliberately introduce each of the following errors, one at a time, and record the compiler's error message:

  1. Remove the semicolon from an emit statement.
  2. Remove the closing } of the main block.
  3. Misspell emit as emitt.
  4. Use single quotes instead of double quotes for a string.

Understanding error messages now will save you significant debugging time later.

Start typing to search...