01
Introduction
Nuru is a programming language written with Swahili words. This reference walks through each part of the language with short examples. Press Jaribu (try it) on any example to open it in Uwanja, change it and run it.
andika("Habari, Dunia!")Output
Habari, Dunia!
andika() prints one or more values. Give it several and Nuru puts a space between them.
andika("Nina miaka", 12)
andika(3 + 4)Output
Nina miaka 127
Comments
Comments are notes for people; Nuru skips them. Use // for one line and /* ... */ for several.
// Huu ni mstari wa maoni
andika("Maoni hayachapishwi")
/*
Maoni ya mistari
mingi
*/Output
Maoni hayachapishwi
02
Variables
A variable is a name that holds a value. Create one with fanya. Later you can give it a new value without fanya.
fanya jina = "Amani"
fanya umri = 12
andika(jina, "ana miaka", umri)
umri = 13
andika(jina, "sasa ana miaka", umri)Output
Amani ana miaka 12Amani sasa ana miaka 13
A variable name starts with a letter or _ and may contain digits: alama1, jina_kamili. Case matters, so Jina and jina are different names. Nuru's own words, such as kama or kwa, cannot be names.
Shortcuts
Updating a variable from its old value is common, so Nuru has shortcuts: +=, -=, *=, ++ and --.
fanya alama = 10
alama += 5 // 15
alama++ // 16
alama -= 2 // 14
alama *= 2 // 28
andika(alama)Output
28
03
Data types
Every value has a type. To find out a value's type, ask Nuru with aina().
| Type | Example | Meaning |
|---|---|---|
NAMBA | 42, -7 | a whole number |
DESIMALI | 3.14, 0.5 | a number with a decimal point |
NENO | "Habari" | text inside quotes |
BOOLEAN | kweli, sikweli | yes or no (true or false) |
TUPU | tupu | no value |
ORODHA | [1, 2, 3] | items kept in order |
KAMUSI | {"jina": "Amani"} | keys and their values |
andika(aina(42))
andika(aina(3.14))
andika(aina("Habari"))
andika(aina(kweli))
andika(aina(tupu))
andika(aina([1, 2, 3]))
andika(aina({"jina": "Amani"}))Output
NAMBADESIMALINENOBOOLEANTUPUORODHAKAMUSI
Converting between types
namba() turns a value into a NAMBA, tungo() turns it into a NENO, and badilisha(value, "TYPE") converts to NAMBA, DESIMALI, NENO or BOOLEAN.
andika(namba("42") + 1)
andika(tungo(42) + "!")
andika(badilisha("3.5", "DESIMALI"))
andika(namba(3.9)) // sehemu ya desimali inaondolewaOutput
4342!3.53
Tip: When you print tupu, Nuru shows null.
04
Operators
Operators do arithmetic, compare values and combine conditions.
Arithmetic
| Operator | Does | Example |
|---|---|---|
+ | add | 2 + 3 → 5 |
- | subtract | 9 - 4 → 5 |
* | multiply | 3 * 4 → 12 |
/ | divide | 7 / 2 → 3.5 |
% | remainder | 7 % 2 → 1 |
** | power | 2 ** 3 → 8 |
andika(7 / 2)
andika(8 / 2)
andika(7 % 2)
andika(2 ** 3)
andika(2 + 3 * 4)
andika((2 + 3) * 4)Output
3.54181420
Multiplication and division happen before addition and subtraction. Use brackets ( ) to change the order.
Comparison
| Operator | Meaning | Example |
|---|---|---|
== | equal to | 5 == 5 → kweli |
!= | not equal to | 5 != 3 → kweli |
< > | less than, greater than | 3 < 5 → kweli |
<= >= | at most, at least | 5 >= 6 → sikweli |
Logic
| Operator | Meaning | Example |
|---|---|---|
&& | and: both are true | kweli && sikweli → sikweli |
|| | or: at least one is true | kweli || sikweli → kweli |
! | not: flips the answer | !kweli → sikweli |
fanya umri = 14
andika(umri >= 13 && umri <= 19)
andika(umri < 5 || umri > 60)
andika(!(umri == 14))Output
kwelisikwelisikweli
Text and ktk
+ joins two pieces of text and * repeats text. ktk (short for "katika", in) asks whether something is inside an orodha, a neno or a kamusi.
andika("Nuru" + " " + "Programu")
andika("ha" * 3)
andika(2 ktk [1, 2, 3])
andika("jina" ktk {"jina": "Amani"})Output
Nuru Programuhahahakwelikweli
Tip: You cannot add a NENO and a NAMBA directly. Turn the number into text first: "Umri: " + tungo(12).
05
Decisions
Programs decide with kama (if). Add au kama (or if) for another condition and sivyo (otherwise) for everything left.
fanya alama = 72
kama (alama >= 80) {
andika("Daraja A")
} au kama (alama >= 60) {
andika("Daraja B")
} sivyo {
andika("Jaribu tena")
}Output
Daraja B
The condition goes inside ( ) and each branch inside { }. Nuru checks the conditions in order and runs only the first branch that is true.
badili, ikiwa, kawaida
When you compare one value against many choices, badili (switch) reads better than a chain of kama. Each ikiwa (case) can list several values separated by commas, and kawaida (default) catches the rest.
fanya siku = "Jumamosi"
badili (siku) {
ikiwa "Jumamosi", "Jumapili" {
andika("Ni wikendi!")
}
ikiwa "Ijumaa" {
andika("Wikendi inakaribia")
}
kawaida {
andika("Siku ya shule")
}
}Output
Ni wikendi!
06
Loops
Loops repeat work. wakati (while) repeats as long as a condition is true. kwa ... ktk (for ... in) visits each item of an orodha, a neno or a kamusi.
wakati
fanya i = 0
wakati (i < 5) {
i++
andika(i)
}Output
12345
Tip: Make sure the condition becomes sikweli at some point, or the loop never ends. In Uwanja, press Simamisha (stop) to halt a stuck program.
kwa ... ktk
fanya matunda = ["embe", "papai", "nanasi"]
kwa tunda ktk matunda {
andika("Napenda", tunda)
}Output
Napenda embeNapenda papaiNapenda nanasi
With two names, the first gets the position (counting from 0) and the second gets the item.
fanya matunda = ["embe", "papai", "nanasi"]
kwa i, tunda ktk matunda {
andika(i, tunda)
}Output
0 embe1 papai2 nanasi
kwa herufi ktk "Nuru" {
andika(herufi)
}Output
Nuru
mfululizo
mfululizo() builds a list of numbers and pairs well with kwa. The end number is not included.
| Call | Result |
|---|---|
mfululizo(5) | [0, 1, 2, 3, 4] |
mfululizo(1, 6) | [1, 2, 3, 4, 5] |
mfululizo(0, 10, 3) | [0, 3, 6, 9] |
mfululizo(5, 0, -1) | [5, 4, 3, 2, 1] |
kwa i ktk mfululizo(1, 6) {
andika(i, "x", i, "=", i * i)
}Output
1 x 1 = 12 x 2 = 43 x 3 = 94 x 4 = 165 x 5 = 25
vunja and endelea
vunja (break) leaves the loop at once. endelea (continue) skips the rest of this round and moves to the next one.
kwa n ktk mfululizo(1, 11) {
kama (n % 2 == 0) { endelea } // ruka namba shufwa
kama (n > 7) { vunja } // simama baada ya 7
andika(n)
}Output
1357
07
Functions
A function is a named piece of code you can call again and again. Create one with unda and send back an answer with rudisha (return).
fanya jumlisha = unda(a, b) {
rudisha a + b
}
andika(jumlisha(2, 3))
andika(jumlisha(10, 32))Output
542
Default arguments
An argument can have a default value, used when the caller leaves it out.
fanya salimu = unda(jina, salamu = "Habari") {
andika(salamu + ", " + jina + "!")
}
salimu("Amani")
salimu("Neema", "Mambo")Output
Habari, Amani!Mambo, Neema!
Functions that make functions
A function is a value like any other: you can store it in a variable or return it. An inner function remembers the variables of the place where it was made (a closure).
fanya zidishaKwa = unda(n) {
rudisha unda(x) {
rudisha x * n
}
}
fanya mara2 = zidishaKwa(2)
fanya mara10 = zidishaKwa(10)
andika(mara2(7), mara10(7))Output
14 70
Tip: An inner function can read outer variables, but assigning a new value to an outer variable does not change the outer one.
Recursion
A function can call itself. Each call solves a smaller problem until it reaches the base case.
fanya kipeo = unda(n) {
kama (n <= 1) { rudisha 1 }
fanya kabla = kipeo(n - 1)
rudisha n * kabla
}
andika(kipeo(5))Output
120
Tip: Store the result of the recursive call in a variable first, like kabla above. The browser build still has a bug that stops the program when you write rudisha n * kipeo(n - 1) directly.
08
Lists (orodha)
An orodha holds many items in order. The first item is at position 0.
fanya rangi = ["nyekundu", "kijani", "bluu"]
andika(rangi[0])
rangi[1] = "njano"
andika(rangi)
andika(rangi[10]) // nafasi isiyokuwepoOutput
nyekundu[nyekundu, njano, bluu]null
Orodha methods
| Method | Does | Example |
|---|---|---|
idadi() | number of items | [4, 5, 6].idadi() → 3 |
sukuma(x, ...) | add one or more items at the end | o.sukuma(7) |
yamwisho() | the last item | [4, 5, 6].yamwisho() → 6 |
unga(kitenganishi) | join the items into one NENO | [1, 2].unga("-") → 1-2 |
tafuta(x) | return x if present, else tupu | [4, 5].tafuta(5) → 5 |
chuja(unda(x) {...}) | keep the items for which the function returns kweli | o.chuja(unda(x) { rudisha x > 2 }) |
map(unda(x) {...}) | a new orodha with the function's answer for each item | o.map(unda(x) { rudisha x * 2 }) |
fanya alama = [70, 85, 40, 92]
andika(alama.idadi())
alama.sukuma(66)
andika(alama)
andika(alama.yamwisho())
andika(alama.unga(" | "))
andika(alama.tafuta(85))
andika(alama.tafuta(100))Output
4[70, 85, 40, 92, 66]6670 | 85 | 40 | 92 | 6685null
fanya alama = [70, 85, 40, 92]
fanya waliofaulu = alama.chuja(unda(a) { rudisha a >= 50 })
fanya zaidi = alama.map(unda(a) { rudisha a + 5 })
andika(waliofaulu)
andika(zaidi)Output
[70, 85, 92][75, 90, 45, 97]
Tip: The function you pass to chuja or map sees only its own argument, not outer variables. Write the numbers it needs directly inside it.
Combining and summing
fanya a = [1, 2]
fanya b = [3, 4]
andika(a + b)
fanya jumla = 0
kwa x ktk a + b {
jumla += x
}
andika("Jumla:", jumla)Output
[1, 2, 3, 4]Jumla: 10
09
Text (neno)
A NENO is text inside quotes, "like this" or 'like this'. Text has its own methods.
| Method | Does | Example |
|---|---|---|
idadi() | number of characters | "Nuru".idadi() → 4 |
herufikubwa() | UPPER CASE | "nuru".herufikubwa() → NURU |
herufindogo() | lower case | "NURU".herufindogo() → nuru |
gawa(kitenganishi) | split into an orodha (on spaces by default) | "a,b".gawa(",") → [a, b] |
panga(...) | fill the slots {0}, {1} ... with the arguments | "Habari {0}".panga("Amani") |
fanya jina = "Nuru Programu"
andika(jina.idadi())
andika(jina.herufikubwa())
andika(jina.herufindogo())
andika(jina.gawa())
andika("embe,papai,nanasi".gawa(","))Output
13NURU PROGRAMUnuru programu[Nuru, Programu][embe, papai, nanasi]
fanya ujumbe = "Habari {0}, una miaka {1}.".panga("Amani", 12)
andika(ujumbe)Output
Habari Amani, una miaka 12.
Tip: {0} is the first argument and {1} the second. Every argument you pass to panga must be used.
Special characters
Inside text, \n starts a new line and \t inserts a tab.
andika("Mstari wa kwanza\nMstari wa pili")Output
Mstari wa kwanzaMstari wa pili
Tip: You cannot take a single character with neno[0]. Walk the characters with kwa herufi ktk neno.
10
Dictionaries (kamusi)
A KAMUSI stores key and value pairs. A key can be a NENO, NAMBA, DESIMALI or BOOLEAN.
fanya mwanafunzi = {"jina": "Amani", "darasa": 5}
andika(mwanafunzi["jina"])
mwanafunzi["shule"] = "Uhuru"
mwanafunzi["darasa"] += 1
andika(mwanafunzi["shule"], mwanafunzi["darasa"])
andika(mwanafunzi["simu"]) // ufunguo usiokuwepo
andika("jina" ktk mwanafunzi)Output
AmaniUhuru 6nullkweli
Looping over a kamusi
fanya bei = {"embe": 500, "papai": 1500, "nanasi": 2000}
kwa tunda, shilingi ktk bei {
andika(tunda, "ni shilingi", shilingi)
}Output
embe ni shilingi 500nanasi ni shilingi 2000papai ni shilingi 1500
Tip: Do not rely on key order. When you print or loop over a whole kamusi, the keys may come out in a different order from how you wrote them.
Join two dictionaries with +: a + b gives a new kamusi with the keys of both.
11
Input: jaza
jaza() asks a question and waits for the user to type an answer. In Uwanja, you type the answer in the terminal under the program.
fanya jina = jaza("Jina lako ni nani? ")
andika("Karibu, " + jina + "!")Output· If you type: Amani
Karibu, Amani!
jaza() always returns a NENO, even when you type a number. Use namba() before doing arithmetic.
fanya umri = namba(jaza("Una miaka mingapi? "))
andika("Mwakani utakuwa na miaka", umri + 1)Output· If you type: 12
Mwakani utakuwa na miaka 13
12
Modules
A module is a library of extra functions. Bring it in with tumia, then call into it with a dot: hisabati.sqrt(16).
hisabati
Deeper maths: roots, angles, logarithms and random numbers.
| Function | Does | Example |
|---|---|---|
PI(), e(), phi() | special constants | hisabati.PI() → 3.141592653589793 |
sqrt(x), cbrt(x) | square root, cube root | hisabati.sqrt(16) → 4 |
root(x, n) | nth root | hisabati.root(27, 3) → 3 |
abs(x) | absolute value | hisabati.abs(-5) → 5 |
sign(x) | -1, 0 or 1 | hisabati.sign(-3) → -1 |
round(x) | round a DESIMALI to a whole number | hisabati.round(2.6) → 3 |
floor(x), ceil(x) | round down, round up | hisabati.floor(2.9) → 2 |
max(orodha), min(orodha) | largest, smallest | hisabati.max([3, 9, 2]) → 9 |
factorial(n) | n! (n × ... × 1) | hisabati.factorial(5) → 120 |
hypot(a, b) | hypotenuse | hisabati.hypot(3, 4) → 5 |
random() | a random number from 0 to 1 | hisabati.random() |
sin, cos, tan, asin, acos, atan | trigonometry (radians, DESIMALI) | hisabati.cos(0.0) → 1 |
exp, log, log10, log2 | exponent and logarithms (DESIMALI) | hisabati.log2(8) → 3 |
tumia hisabati
andika(hisabati.sqrt(16))
andika(hisabati.PI())
andika(hisabati.max([3, 9, 2]))
andika(hisabati.round(2.6))
andika(hisabati.factorial(5))
andika(hisabati.cos(0.0))Output
43.141592653589793931201
tumia hisabati
fanya kete = hisabati.floor(hisabati.random() * 6) + 1
andika("Kete imeonyesha", kete)Output (sample)
Kete imeonyesha 4
Tip: PI() and e() are functions, so include the brackets. The angle functions, round, exp and log accept only a DESIMALI: write hisabati.cos(0.0), not hisabati.cos(0).
muda
Time, dates and waiting. Times look like hour:minute:second day-month-year.
| Function | Does | Example |
|---|---|---|
hasahivi() | the current time | muda.hasahivi() |
leo() | today's date | muda.leo() → 12-10-2026 |
lala(sekunde) | wait a number of seconds | muda.lala(1) |
tangu(m) | seconds since time m | muda.tangu(mwanzo) |
baada_ya(sekunde) | the time some seconds from now | muda.baada_ya(60) |
tofauti(a, b) | seconds between two times | muda.tofauti(b, a) |
ongeza(m, dakika=5) | add sekunde, dakika, masaa, siku, wiki, miezi or miaka | muda.ongeza(m, siku=1) |
tumia muda
fanya mwanzo = muda.hasahivi()
andika("Leo ni", muda.leo())
muda.lala(1)
andika("Sekunde zilizopita:", muda.tangu(mwanzo))Output (sample)
Leo ni 12-10-2026Sekunde zilizopita: 1
jsoni
Read and write JSON, the data format most websites use.
| Function | Does |
|---|---|
dikodi(neno) | turn JSON text into a kamusi or orodha |
enkodi(thamani) | turn a kamusi or orodha into JSON text |
tumia jsoni
fanya data = jsoni.dikodi("{\"jina\": \"Amani\", \"alama\": [90, 85]}")
andika(data["jina"])
andika(data["alama"])
andika(jsoni.enkodi({"somo": "Nuru"}))Output
Amani[90, 85]{"somo":"Nuru"}
kobe
Kobe is a small turtle that draws on a 600 × 600 canvas. It starts in the middle at (0, 0) facing east (right), and y grows upwards. A program with tumia kobe opens in Uwanja next to the canvas.
| Function | Does |
|---|---|
mbele(n), nyuma(n) | move forward or back n steps |
kulia(digrii), kushoto(digrii) | turn right or left |
elekea(digrii) | face a direction: 0 east, 90 north |
nenda(x, y) | go straight to (x, y) |
nyumbani() | return to the middle, facing east |
kalamu_juu(), kalamu_chini() | lift the pen (move without drawing), put it down |
rangi(r) | pen colour |
rangi_ya_ndani(r) | fill colour |
anza_kujaza(), maliza_kujaza() | start a shape, then fill it |
unene(n) | line width |
duara(r) | draw a circle of radius r around the turtle |
nukta(ukubwa) | draw a dot |
maandishi(neno, ukubwa) | write text on the canvas |
mandhari(r) | background colour |
kasi(n) | drawing speed: 0 instant to 10 |
futa() | clear the canvas |
ficha(), onyesha() | hide or show the turtle |
mahali() | return [x, y] |
mwelekeo() | return the heading in degrees |
Colours: nyeusi (black), nyeupe (white), nyekundu (red), kijani (green), bluu (blue), samawati (sky blue), njano (yellow), machungwa (orange), zambarau (purple), waridi (pink), kahawia (brown), kijivu (grey), dhahabu (gold), fedha (silver), or a code such as "#ff8800".
tumia kobe
kobe.rangi("bluu")
kobe.unene(4)
kwa i ktk mfululizo(4) {
kobe.mbele(150)
kobe.kulia(90)
}
andika(kobe.mahali())Output
[0, 0]
Watch the kobe canvas.
tumia kobe
kobe.rangi("nyekundu")
kobe.rangi_ya_ndani("njano")
kobe.nenda(-100, 30)
kobe.anza_kujaza()
kwa i ktk mfululizo(5) {
kobe.mbele(200)
kobe.kulia(144)
}
kobe.maliza_kujaza()Output
No printed output. Watch the kobe canvas.
tumia kobe
fanya rangi = ["nyekundu", "machungwa", "njano", "kijani", "bluu", "zambarau"]
kobe.kalamu_juu()
kwa i, r ktk rangi {
kobe.nyumbani()
kobe.elekea(i * 60)
kobe.mbele(120)
kobe.rangi(r)
kobe.nukta(50)
}
kobe.nyumbani()
kobe.rangi("nyeusi")
kobe.maandishi("Nuru", 28)Output
No printed output. Watch the kobe canvas.
ubao
Ubao is a simulated electronics board: 8 lights (numbered 1 to 8), a buzzer and a small screen of 2 lines with 16 characters each. It is the first step before real hardware.
| Function | Does |
|---|---|
washa(n), zima(n) | turn light n on or off |
geuza(n) | toggle a light |
washa_zote(), zima_zote() | turn every light on or off |
imewaka(n) | return kweli if the light is on |
rangi(n, r) | colour of light n |
kengele(hz, ms) | sound the buzzer: pitch in Hz, length in milliseconds |
skrini(neno) | write on the small screen |
subiri(ms) | wait some milliseconds |
tumia ubao
ubao.skrini("Taa zinawaka")
kwa i ktk mfululizo(1, 9) {
ubao.washa(i)
ubao.subiri(150)
}
ubao.kengele(880, 300)
ubao.zima_zote()Output
No printed output. Watch the board.
tumia ubao
ubao.rangi(1, "nyekundu")
ubao.rangi(2, "njano")
ubao.rangi(3, "kijani")
kwa taa ktk [1, 2, 3] {
ubao.washa(taa)
ubao.subiri(700)
ubao.zima(taa)
}
andika(ubao.imewaka(3))Output
sikweli
Watch the board.
13
Common errors
Nuru explains errors in Swahili and names the line where they happened. These are the ones you will meet most often.
| Message | What it means | Fix |
|---|---|---|
Neno Halifahamiki: x | you used a name that was never created | create it with fanya first, or check the spelling |
Aina Hazilingani: NENO + NAMBA | you mixed two types that do not go together | convert with tungo() or namba() |
Operesheni Haieleweki: NENO < NENO | this operator does not work on this type | use a different operator |
Tulitegemea kupata ), badala yake tumepata MWISHO | a bracket was not closed; MWISHO is the end of the code | |
Hukufunga Mabano '}' | a { has no matching } | add the } |
Tulitegemea kupata (, badala yake tumepata KITAMBULISHI | kama or wakati without ( ) | write kama (x > 3) { ... } |
Hiki sio kiendesha: NAMBA | you called something that is not a function | |
Tumekosa Hoja | a function was called with too few arguments | |
Samahani, kiendesha hiki hakitumiki na tungo (Neno) | that method does not exist on this orodha or neno | check the Orodha and Neno tables |
Haiwezi kubadilisha 'abc' kuwa NAMBA | namba() got text that is not a number | |
Moduli sayari haipo | there is no module with that name | see the Moduli section |
Hoja lazima iwe desimali | a hisabati function needs a DESIMALI | write 0.0 instead of 0 |
A few words come up again and again: Mstari is the line number, Hoja is a value you pass to a function, KITAMBULISHI is a name, and HARAMU is a character Nuru does not know.
fanya jina = "Amani"
andika(Jina)Output
Kosa: Mstari 2: Neno Halifahamiki: Jina
fanya umri = 12
andika("Umri: " + umri)Output
Kosa: Mstari 2: Aina Hazilingani: NENO + NAMBA
fanya x = 5
kama x > 3 {
andika("kubwa")
}Output
Kuna makosa yafuatayo:Mstari 2: Tulitegemea kupata (, badala yake tumepata KITAMBULISHIMstari 3: Tulitegemea kupata :, badala yake tumepata }Mstari 4: Tumeshindwa kuparse }
Tip: One syntax mistake can produce several messages. Fix the first message, then run again.