Introduction
Welcome to NaijaScript, where programming meets cultural authenticity.
This book will teach you a scripting language that speaks Nigerian Pidgin English literally, removing artificial barriers between thought and computational expression.
Motivation
Programming should not require abandoning your cultural identity.
For over 75 million speakers of Nigerian Pidgin English, learning to code has meant translating thoughts between languages before expressing computational logic.
NaijaScript eliminates this cognitive overhead by embracing authentic Pidgin expressions as first-class programming constructs.
When you write:
make age get 25
if to say (age pass 18) start
shout("You fit vote!")
end
you are not just writing code but thinking computationally in your natural linguistic patterns.
This is more than syntax translation. It represents a fundamental shift toward inclusive technology that recognizes linguistic diversity as strength. By removing artificial barriers, NaijaScript opens programming education to millions while demonstrating that powerful software can emerge from any cultural context.
The language proves this philosophy through performance. In benchmarks, NaijaScript often outperforms JavaScript and Python in string manipulation, mathematical computation, and algorithmic tasks making cultural authenticity and technical excellence complementary goals.
Read more in this article.
Limitations
While NaijaScript aims to be a practical scripting language, it currently has some limitations:
- No package management or extensive standard library yet
- Designed for educational and scripting use cases, not large-scale applications
- Lacks IDE support and advanced tooling
What you will learn
- How to install NaijaScript and run the interpreter
- The language syntax and core semantics
Ready to begin? Let's start with installation.
Installation
NaijaScript runs on Linux, macOS, and Windows.
Quick install (recommended)
Linux/macOS
curl --proto '=https' --tlsv1.2 -LsSf https://raw.githubusercontent.com/xosnrdev/naijascript/master/scripts/install.sh | sh
Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/xosnrdev/naijascript/master/scripts/install.ps1 | iex"
These scripts download the latest stable release, install the naija interpreter, and add the install directory to your PATH. You may need to restart your terminal after installation.
Verify the install
naija --version
Expected output example:
naijascript 0.11.5
First program
Create hello.ns:
shout("Hello, World!")
Run it:
naija hello.ns
For help:
naija help
Web playground
Try NaijaScript in your browser: https://naijascript-playground.pages.dev
Development setup
- Clone the repository
git clone https://github.com/xosnrdev/naijascript.git
cd naijascript
- Ensure Rust tooling
Install Rust via rustup if you do not have it. The repository pins the toolchain in rust-toolchain.toml; rustup will select the required nightly toolchain automatically.
- Build the interpreter
cargo build --bin naija
- Run tests
cargo test
If you encounter any issues, feel free to open an issue on the GitHub repository.
Variables
Declaration
Declare a variable with an initial value:
make foo get 42
make bar get "hello"
make baz get true
You can also declare a variable without an initial value. That creates an uninitialized variable whose value is null:
make foo
make bar
Assignment
Assign or reassign a variable:
foo get 10
bar get foo
Shadowing
NaijaScript allows redeclaring the same variable name in the same scope. The most recent declaration in that scope is used at runtime:
make foo get 1
make foo get 2 # This shadows the earlier foo in the same scope
foo # evaluates to 2
Inner blocks can shadow outer variables. The inner declaration hides the outer one until the inner block ends:
make foo get 1
start
make foo get 2
foo # inner foo is 2
end
foo # outer foo is still 1
Comments
Any text following a # symbol on a line is treated as a comment and ignored by the interpreter.
Single-line
# This is a full-line comment
make foo get 1
# Comment between statements
make bar get 2
Inline
make foo get 1 # initialize foo
make bar get foo # copy foo to bar
make baz get 3 # set baz to 3
Numbers
NaijaScript numbers are IEEE-754 floating point values that can represent both integers and decimals.
Literals
Declare numeric values:
make foo get 42
make bar get 3.14
make baz get minus 2.5
Methods
Available methods and return types:
| Method | Description | Returns |
|---|---|---|
abs() | Absolute value | Number |
sqrt() | Square root | Number |
floor() | Round down to the nearest integer | Number |
ceil() | Round up to the nearest integer | Number |
round() | Round to the nearest integer | Number |
Examples
Call methods on literals and variables:
make foo get (minus 3.5).abs()
make bar get 9.0.sqrt()
make baz get 2.7.floor()
Use methods on variables and chain calls:
make foo get minus 2.5
make bar get foo.abs()
make baz get (minus 2.5).abs().sqrt()
Operators
Available arithmetic operators:
| Operator | Description |
|---|---|
add | Addition |
minus | Subtraction |
times | Multiplication |
divide | Division |
mod | Modulo |
Strings
NaijaScript strings are UTF-8 encoded and support Unicode characters.
Literals
Declare string values:
make foo get "Aisha"
make bar get " hello "
Concatenation and interpolation
Concatenate with add and interpolate with braces:
make foo get "Hello, " add "Aisha" add "!"
make bar get "Hello, {foo}!"
Methods
Available methods and return types:
| Method | Description | Returns |
|---|---|---|
len() | Number of Unicode code points in the string | Number |
slice(start, end) | Substring from start (inclusive) to end (exclusive). start/end are floored; negative indexes count from end. | String |
to_uppercase() | Convert to uppercase | String |
to_lowercase() | Convert to lowercase | String |
find(needle) | Index of first occurrence (0-based). Returns -1 if not found. | Number |
replace(old, new) | Replace all occurrences of old with new | String |
trim() | Remove leading and trailing whitespace | String |
to_number() | Parse the string as a number, or NaN on failure | Number |
Booleans
NaijaScript booleans are simple true/false values.
Literals
Declare boolean values:
make foo get true
make bar get false
Methods
Boolean methods are currently planned and not yet available.
Operators
Available logical operators:
| Operator | Description |
|---|---|
and | logical conjunction |
or | logical disjunction |
not | logical negation |
Arrays
NaijaScript arrays hold heterogeneous values and are written with square brackets.
Literals
Declare arrays:
make foo get ["apple", "banana", "orange"]
make bar get [1, 2, 3, 4]
make mixed get ["text", 42, true]
make nested get [[1, 2], [3, 4]]
Indexing and assignment
Access elements with zero-based indexes and assign by indexing:
make foo get ["a", "b", "c"]
make first get foo[0] # "a"
foo[1] get "bee" # foo becomes ["a", "bee", "c"]
Nested arrays use chained indexes:
make nested get [[1,2], [3,4]]
make val get nested[1][0] # 3
nested[0][1] get 9 # nested becomes [[1,9], [3,4]]
Methods
Available methods and return types:
| Method | Description | Returns |
|---|---|---|
len() | Number of elements in the array | Number |
push(value) | Append value to the end of the array | Array |
pop() | Removes the last element of the array (if any) | Array |
Note: push and pop mutates the array and yields the array for chaining.
Null
Null represents the absence of a value. It is a distinct runtime value, different from true, false, 0, or the empty string. In boolean contexts, null is falsy.
Literals
Declare null values:
make foo get null
A function with no return value implicitly returns null:
do do_nothing() start
# no return statement
end
shout(typeof(do_nothing())) # prints "null"
Comparisons
null can be compared using the na (equal to) operator:
make foo get null
make baz get null
shout(foo na baz) # prints true
shout(foo na 0) # prints false
shout(foo na "") # prints false
shout(foo na false) # prints false
Boolean context
null behaves as falsy in conditional checks:
if to say(not null) start
shout("null is falsy")
end
Conditionals
Conditionals control flow by evaluating boolean expressions and running code blocks when those expressions are true.
Syntax
if to say (condition) start
# Executes block if condition is true
end
if not so start
# Executes block if condition is false
end
Operators
Available comparison operators:
| Operator | Description |
|---|---|
na | equal to |
pass | greater than |
small pass | less than |
Examples
If statement:
if to say (foo pass 10) start
shout("foo is greater than 10")
end
Else statement:
if to say (foo na 0) start
shout("foo is zero")
end
if not so start
shout("foo is not zero")
end
Else-if statement:
make n get 3
if to say (n small pass 2) start
shout("small")
end
if not so start
if to say (n na 2) start
shout("exactly two")
end
if not so start
shout("greater than two")
end
end
Loops
Loops repeat a block while a boolean condition holds. NaijaScript uses the jasi construct for pre-checked looping (while-style).
Syntax
jasi (condition) start
# Executes block continuously while condition is true
end
Operators
Available comparison operators:
| Operator | Description |
|---|---|
na | equal to |
pass | greater than |
small pass | less than |
Examples
Simple counter loop (prints 0 through 4):
make foo get 0
jasi (foo small pass 5) start
shout(foo)
foo get foo add 1
end
FizzBuzz (1 to 100):
make foo get 1
jasi (foo small pass 101) start
if to say (foo mod 15 na 0) start
shout("FizzBuzz")
end
if not so start
if to say (foo mod 3 na 0) start
shout("Fizz")
end
if not so start
if to say (foo mod 5 na 0) start
shout("Buzz")
end
if not so start
shout(foo)
end
end
end
foo get foo add 1
end
Loop Control Flow
Break Statement (comot)
Exit the innermost loop immediately:
make i get 0
jasi (i small pass 10) start
if to say (i na 5) start
comot # Exit loop when i reaches 5
end
shout(i)
i get i add 1
end
# Prints: 0, 1, 2, 3, 4
Continue Statement (next)
Skip to the next iteration of the innermost loop:
make i get 0
jasi (i small pass 5) start
i get i add 1
if to say (i mod 2 na 0) start
next # Skip even numbers
end
shout(i)
end
# Prints: 1, 3, 5
Nested Loops
comot and next affect only the innermost loop:
make outer get 0
jasi (outer small pass 3) start
make inner get 0
jasi (inner small pass 3) start
if to say (inner na 1) start
comot # Exits inner loop only
end
inner get inner add 1
end
outer get outer add 1
end
Functions
Definition
Define a function with do name(params) start ... end:
do hello() start
shout("hello")
end
Functions can accept zero or more parameters:
do add(foo, bar) start
return foo add bar
end
Parameters
Parameters are local names bound to the arguments passed at call time:
do greet(name) start
shout("Hello {name}")
end
make foo get "Ada"
greet(foo)
Return
Use return to send a value back to the caller:
do max(foo, bar) start
if to say (foo small pass bar) start
return bar
end
return foo
end
make result get max(3, 7)
If a function does not execute a return, it produces no value for the caller.
Calling functions
Call a function by its name and argument list. You may use the result in expressions or assignments:
make x get add(2, 3)
shout("x = {x}")
Scope and locals
Variables declared with make inside a function are local to that function. They do not affect the caller’s scope unless returned and assigned:
do example() start
make foo get 1
make bar get 2
return foo add bar
end
make foo get 10
make result get example()
shout("outer foo = {foo}") # outer foo still 10
Built-in Functions
I/O functions
shout(value)
Prints value to the console.
Example:
shout("Hello, World!")
read_line(prompt)
Prompts the user and reads a single line from standard input. Returns a string with the line.
Example:
make name get read_line("Enter name: ")
shout("Hello {name}")
Introspection
typeof(value)
Returns the runtime type of value as a string: "number", "string", "boolean", "array", or "null".
Example:
make foo get 42
make t get typeof(foo)
shout("foo is a {t}")
to_string(value)
Converts the given value to its string representation.
Example:
make x get 42
make s get to_string(x)
shout(s)