Your first program
In this lesson you write and run your first Salam program, learn the handful of commands you will use every day, and get a feel for what Salam code looks like.
Hello, world
Every Salam program starts at func main, the first thing that runs. A block opens with a colon (:) and closes with end, and indenting the lines inside it keeps the code readable. Text goes between double quotes, and println takes its value without parentheses.
func main:
println "Hello, world!"
endRunning a program
Save your code in a file with a .salam extension, say hello.salam. salam run hello.salam compiles it and runs it straight away. If you want a standalone executable instead, use salam build hello.salam and a native binary appears next to your source. You can also run every example here in the online editor without installing anything.
| Command | What it does |
|---|---|
salam run hello.salam | Compiles the program, runs it, and keeps nothing afterwards |
salam build hello.salam | Builds a native executable named hello that runs without Salam installed |
salam exec hello.salam | Runs the program in the interpreter, with no C compiler involved |
salam format hello.salam | Rewrites the file in the standard layout; --check only reports |
salam translate fa hello.salam | Writes a Persian copy, hello.fa.salam; translate en goes the other way |
salam new shop | Creates a project folder shop with a salam.salam inside; salam run in that folder runs it |
salam version | Prints the version of the compiler |
salam update | Upgrades the compiler and its standard library to the newest release; --check only reports whether one is out |
Printing output
println prints its values and moves to the next line; print stays on the same line. Separate several values with commas and Salam writes them out with one space between them.
func main:
println "Hello", "world"
print "no "
print "line break"
println ""
println "today it is", 20, "degrees"
endAny value can be printed as it is: whole and decimal numbers, true and false, the result of a calculation, even a whole list. Here is a small receipt:
func main:
println "Receipt"
println "notebook", 3, "x", 45
println "pen", 2, "x", 12
println "total:", 3 * 45 + 2 * 12
println "average per item:", (3 * 45 + 2 * 12) / 5.0
println "paid in full:", true
println "aisles:", [4, 7]
endThree rules cover nearly every printing mistake:
- No parentheses around the values:
println "hi", notprintln("hi"). - A comma between every two values:
println "a", "b". Leaving it out is an error, not a joined string. printlnalways needs a value. For an empty line writeprintln "".
For error messages use printerrln and printerr. They write to standard error, so they stay out of the program's real output and survive being piped elsewhere: with salam run app.salam > out.txt, the normal lines land in the file and the errors still show on screen.
func main:
println "this line goes to standard output"
printerrln "this line goes to standard error"
endExit codes
When a program ends it hands the operating system a number, its exit code. Zero means success and anything else means something went wrong; scripts and build tools read it to decide whether to carry on. Give main the return type int and the value you ret becomes the exit code. A plain func main: that simply reaches its end exits with 0.
func main: int:
free_mb := 820
needed_mb := 500
if free_mb < needed_mb:
printerrln "not enough space:", free_mb, "MB free,", needed_mb, "MB needed"
ret 1
end
println "enough space, starting the backup"
ret 0
endWith 820 MB free the check passes and the program returns 0. Change free_mb to 300 and it prints the message to standard error and exits with 1, which you can see with echo $? right after running it in a Unix shell.
Reading input
input reads one line from the user and gives it back as a string. Like print it takes no parentheses, and it always wants a prompt, which it prints before reading. If you do not want one, write input "". What comes back is always text; when you need a number, convert it with to_int() (or to_float() for decimals):
func main:
name := input "Your name: "
tickets := input "How many tickets? "
total := tickets.to_int() * 12
println "Thank you,", name
println "That comes to", total, "dollars"
endIf the user types something that is not a number, to_int() gives 0 rather than stopping the program, so check the value before trusting it. This example waits for a person at the keyboard, which is why it shows no output here.
Comments
Anything after // to the end of the line, and anything between /* and */, is a comment and is not run.
// this is a single line comment and is not run
/*
A block comment:
anything between these two markers is ignored.
*/
func main:
println "comments never show up in the output" // this is a comment too
endBlock comments nest: a /* ... */ inside another one is fine, so you can wrap a stretch of code that already contains a block comment to switch it off for a moment.
One line blocks
When the body of a block is short, you can put the whole thing on one line:
func main: println "a one line program" endThe shape of a program
A real program is more than main. A source file is read from the top, in this order: import lines for libraries, then constants, then global variables, then your own types, then functions. Functions can call each other in any order, so main is free to sit at the top and use helpers that are written further down.
import str
const SHOP := "Salam Books"
func main:
println SHOP
println divider()
println line("The Little Prince", 2)
println line("Dune", 1)
end
func divider(): str:
ret str.Repeat("-", 20)
end
func line(title: str, copies: int): str:
ret title + " x " + copies
endimport str brings in the string library, and str.Repeat is one of its functions; the packages lesson covers libraries properly. A constant below a function, or an import below a constant, is a compile error that tells you where to move it.
When the compiler says no
Salam checks a lot before it runs anything, and it points at the exact line and column with a message that says what to do. These are the ones a beginner meets first:
| You wrote | The compiler says |
|---|---|
println("hi") | print arguments must not be wrapped in parentheses; remove them |
println on its own | print needs a value: write 'println ""' for an empty line |
println "a" "b" | expected ',' between the values to print |
x := 5, and x is never used | E059: unused variable 'x' |
a && b | '&&' is not a Salam operator; write 'and' |
Read the first message first: one mistake can cause a few more errors below it, and those usually go away once the first is fixed. The compiler rules lesson explains the stricter checks and why they help.
Salam is bilingual: every program on this site can also be written with Persian words. The keyword lesson has the full table.