Do. Simple to say, simpler to code.

Forget about &&, ||, and !. Embrace the elegance of Do: a minimalist language that replaces symbols with the clarity of plain English.

IDE (Desktop)Read the DocsIDE Mobile

Tutorial

Everything you need to write Do programs.

1. Hello World

print "Hello World"

2. Data Types

go count = 10
go price = 12.5
go name = "John"
go active = true
go empty = null
go list = [1, 2, 3]
go person = {"name": "John", "age": 30}

3. Variables & Constants

go declares a mutable variable. let declares an immutable constant.

go age = 4
age = 2         note works fine

let pi = 3.14
pi = 4          note Runtime Error: Cannot reassign a let value

4. Naming Rules

Identifiers: lowercase start, camelCase, letters and digits only. Kind names use PascalCase.

ValidInvalid
player1Player (reserved for kinds)
userScoremy_score
checkPerson2age

5. Input & F-Strings

ask always returns a string. F-strings evaluate expressions inside {}.

go name = ask "Enter your name:"
print f"Hello, {name}"

go x = 5
go y = 0 minus 2
print f"Result: {x plus y}"  note Result: 3

6. Math Operations

OperationKeyword
Additionplus
Subtractionminus
Multiplicationtimes
Divisionover
Modulusmod
Exponentexp

The - symbol is for negation only. Use minus for subtraction.

go x = -5          note negative literal
go a = 10
print -a            note -10 (negation)
go y = -a plus 3   note -7
go z = 5 - 3       note ERROR: use 'minus'

7. String Arithmetic

plus concatenates. times repeats.

print "Hello" plus "World"  note HelloWorld
print "do" times 3          note dododo

8. Comparisons & Logic

print 5 is 5          note true
print 5 isNot 2       note true
print 10 above 8      note true
print 3 below 8       note true
print 10 atLeast 10   note true
print 2 atMost 3      note true

print true and false   note false
print true or false    note true
print not false        note true

Non-empty strings are truthy. Empty strings are falsy.

9. Control Flow

go age = 19
if age below 13
  print "Child"
otherwise age below 18
  print "Teen"
else
  print "Adult"
endIf

10. Loops

For Loop

go numbers = [1, 2, 3]
for number in numbers
  print number
endFor

While Loop

go x = 0
while x below 5
  print x
  x = x plus 1
endWhile

skip continues to the next iteration. stop breaks out of the loop.

11. Functions

Declare with do, return with give, pass arguments with with and and.

do checkPerson with name and age
  if name is "John" and age is 30
    print true
  else
    print false
  endIf
endDo

checkPerson with "John" and 30

Call with no arguments: myFunc()

12. Lists

go fruits = ["apple", "banana"]
print fruits at [0]    note apple
fruits.push["cherry"]
fruits.pop[]

Built-in Methods

MethodDescription
.max[].min[]Maximum / minimum
.sum[] .avg[]Sum / average
.sort[]Sort ascending
.reverse[]Reverse order
.Join[sep]Join into string
.Shuffle[]Random shuffle
.clear[]Remove all elements

13. Catalogs

let user = {"name": "Alice", "lv": 5}
print user.name  note Alice

go player = {"hp": 100}
player.hp = 80

14. String Operations

go hello = "hello"
print hello.length[]       note 5
print hello.split[]        note ["h", "e", "l", "l", "o"]
print hello.contains["h"] note true

15. Type Conversion

Postfix operators. Can be chained.

print "42" toInt            note 42
print 3.14 toStr           note 3.14
print "3.14" toFloat        note 3.14
print 1 toBool              note true
print "42.9" toFloat toInt  note 42

print typeOf("hello")   note string
print typeOf(42)        note integer

16. Random

go val = random from 0 to 500 with 3 digits
go whole = random from 1 to 10 with 0 digits

17. Comments

note This is a single-line comment

note
  This is a multi-line comment
  It spans multiple lines
endNote

18. Kinds (Classes)

Reusable structures with properties and methods. Names use PascalCase.

Declaration

kind Person with name and age
endKind

go john = new Person with "John" and 32
print john.name  note John

Methods

kind Square with l and w
  do getArea
    give this.l times this.w
  endDo
endKind

go sq = new Square with 5 and 10
print sq.getArea()  note 50

Inheritance

kind Animal with name
endKind

kind Rabbit extends Animal
  do speak
    print f"I am {this.name}"
  endDo
endKind

go bunny = new Rabbit with "Bugs"
bunny.speak()  note I am Bugs

Child kinds inherit all parent methods and can override them.

19. Async / Await / Fetch

async do getData with url
  go response = await fetch with url
  give response.body
endDo

go data = await getData with "https://api.example.com/data"

fetch returns {"status": 200, "ok": true, "body": ...}. JSON auto-parses.

Fetch with options

go options = {
  "method": "POST",
  "headers": {"Content-Type": "application/json"},
  "body": {"name": "John"}
}
go res = await fetch with "https://api.example.com/users" and options

20. Ternary

go val = 100
go result = val above 50 when true "big" otherwise "small"
print result  note big

21. Import / Export

export let PI = 3.14159

export do square with n
  give n times n
endDo

from "math_utils.do" import PI and square

Documentation

Formal grammar and token reference for the Do language.

EBNF Grammar

program           = { statement } EOF ;

statement         = simpleStatement NEWLINE

                  | blockStatement ;

simpleStatement   = printStmt

                  | varDecl

                  | assignment

                  | funcCall

                  | returnStmt

                  | loopControl

                  | importStatement

                  | exportStatement

                  | comment ;


blockStatement    = ifStmt

                  | forStmt

                  | whileStmt

                  | funcDecl

                  | kindDecl

                  | multiLineComment ;

printStmt         = "print" expression ;

varDecl           = ("go" | "let") identifier "=" expression ;

assignment        = ( identifier | thisExpr | memberAccess ) "=" expression ;

expression        = askExpr | ternaryExpr | logicExpr ;

askExpr           = "ask" string ;

ternaryExpr       = logicExpr "when" "true" expression

                    "otherwise" expression ;

logicExpr         = comparisonExpr

                    { ("and" | "or") comparisonExpr } ;

comparisonExpr    = mathExpr

                    [ comparisonOp mathExpr ] ;

comparisonOp      = "is" | "isNot" | "above" | "below"

                  | "atLeast" | "atMost" ;

mathExpr          = term { ("plus" | "minus") term } ;

term              = factor { ("times" | "over" | "mod") factor } ;

factor            = unary [ "exp" factor ] ;

unary             = [ "not" | "-" ] postfix ;

postfix           = primary { conversionOp } ;

conversionOp      = "toStr" | "toInt" | "toFloat" | "toBool" ;

primary           = literal | identifier | funcCall | randomCall

                  | indexAccess | methodCall | propertyAccess

                  | list | catalog | fString | newExpr

                  | awaitExpr | fetchExpr | thisExpr | typeOfExpr

                  | "(" expression ")" ;

literal           = INTEGER_LITERAL | FLOAT_LITERAL | STRING_LITERAL

                  | BOOLEAN_LITERAL | NULL_LITERAL ;

list              = "[" [ expression { "," expression } ] "]" ;

indexAccess       = identifier "at" "[" expression "]" ;

catalog           = "{" [ pair { "," pair } ] "}" ;

pair              = string ":" expression ;

propertyAccess    = expression "." identifier ;

methodCall        = expression "." methodName

                    ( "[" [ expression { "," expression } ] "]"

                    | "(" ")"

                    | "with" expression { "and" expression } ) ;

methodName        = "push" | "pop" | "max" | "min" | "avg" | "sum" | "sort" | "shuffle" | "clear" | "reverse" | "join" | "split" | "contains" | "length" ;

randomCall        = "random" "from" expression "to" expression

                    "with" expression ("digit" | "digits") ;

fString           = "f" string ;

typeOfExpr        = "typeOf" "(" expression ")" ;

funcDecl          = [ "async" ] "do" identifier

                    [ "with" identifier { "and" identifier } ]

                    NEWLINE { statement } "endDo" ;

funcCall          = identifier

                    ( "(" ")"

                    | "with" expression { "and" expression } ) ;

returnStmt        = "give" expression ;


ifStmt            = "if" expression NEWLINE

                    { statement }

                    { "otherwise" [ expression ] NEWLINE { statement } }

                    [ "else" NEWLINE { statement } ]

                    "endIf" ;

forStmt           = "for" identifier "in" identifier NEWLINE

                    { statement }

                    "endFor" ;

whileStmt         = "while" expression NEWLINE

                    { statement }

                    "endWhile" ;

loopControl       = "skip" | "stop" ;

kindDecl          = "kind" KIND_NAME [ "extends" KIND_NAME ]

                    [ "with" identifier { "and" identifier } ]

                    NEWLINE { funcDecl } "endKind" ;

newExpr           = "new" KIND_NAME

                    [ "with" expression { "and" expression } ] ;

thisExpr          = "this" "." identifier ;

awaitExpr         = "await" expression ;



fetchExpr         = "fetch" "with" expression

                    [ "and" expression ] ;

importStatement   = "from" string "import" identifier { "and" identifier }

                  | "import" string "as" identifier ;

exportStatement   = "export" ( varDecl | funcDecl ) ;
comment           = "note" [ noteText ] ;

multiLineComment  = "note" NEWLINE { noteText } "endNote" ;

identifier        = lowercaseLetter

                    { lowercaseLetter | uppercaseLetter | digit } ;

KIND_NAME         = uppercaseLetter

                    { lowercaseLetter | uppercaseLetter | digit } ;

Token Model

Keywords

go let print ask if otherwise else when for in while do give skip stop note endNote endIf endFor endWhile endDo with at from to digit digits random import export as typeOf

Async Keywords

async await fetch

Kind Keywords

kind endKind new extends this

Word Operators

and or not plus minus times over mod exp is isNot above below atLeast atMost

Type Conversions

toStr toInt toFloat toBool

Methods

push pop max min avg sum sort shuffle clear reverse join split contains length

String Literals

STRING "..."   F_STRING f"...{expr}..."

Numeric Literals

INTEGER 42   FLOAT 3.14

Boolean & Null

true false null

Comments

note ... (single-line)   note ... endNote (multi-line)

Identifiers

IDENTIFIER [a-z][a-zA-Z0-9]*   KIND_NAME [A-Z][a-zA-Z0-9]*

Symbols & Delimiters

= . ( ) [ ] { } , : - NEWLINE EOF