Bau is a simple, concise, safe, powerful and fast programming language. Features:
Try it out in the browser. And try out the WASM C compiler (soon to be integrated).
It addresses other languages' issues:
fun fact(x int) int
if x <= 1
return 1
return x * fact(x - 1)
for i:= range(0 20)
println(fact(i))
Control flow
if
elif
else
for
while
break
continue
return
throw
catch
switch
case
Assignment, comparison, operations
:
constant, :=
variable=
+=
-=
*=
/=
etc. update=
<
>
<=
>=
!=
and
or
not
+
-
*
/
%
&
|
^
~
<<
>>
bitwiseData types and miscellaneous
int
i32
i16
i8
, f64
f32
#
comment, ##
block commentfun
type
enum
definitions()
[]
.
..
,
'
`
?
import
module
null
const
Identifiers contain letters, digits, and _
.
:
defines a constant.
:=
defines a variable. =
+=
-=
*=
/=
&=
|=
^=
<<=
>>=
updates it:
PI : 3.14159
x := 10
x = x + 1
x += 1 # shortcut
The built-in types are int
i32
i16
i8
(signed integer),
and f64
f32
(floating point).
int
can be restricted to a range using 0..
.
Defaults are int
and f64
; both are 64 bit.
Conversion functions change the type, and may truncate.
c := i8(10)
if
starts a condition.
Spaces group statements into blocks.
elif
("else if") and else
are optional.
if a = 0
println('zero')
elif a = 1
println('one')
else
println('many')
There are for
and while
loops.
,
is optional if the arguments are simple:
# loop from 0 to 9
for i := range(0 10)
println(i)
for
is internally converted to while
:
i := 0
while i < 10
println(i)
i += 1
break
exits a loop. It may have a condition:
# prints 1 to 4
for i := range(0 10)
break i = 5
println(i)
#
starts a line comments;
two or more start and end a block comment.
# Line comment
##
Block comment
##
Comments before types and functions are converted to documentation.
Numbers start with a digit. _
is ignored.
.
is floating point, 0x
hexadecimal.
Strings starting with '
may contain \n
newline, \t
tab, \'
single quote,
\\
backslash, \x00
byte. UTF-8 is used.
Raw strings don't have escapes
and start and end with one or more `
.
Multi-line ones begin on the next line
and may be indented.
a : 1_000_000
b : 3.1415
c : 0xcafe
d : 'String literal'
e : `Raw string`
f : ``
Two-line
raw string with `
``
=
<
>
<=
>=
!=
compare two values and return 1
or 0
.
and
or
not
combine comparisons.
and
or
only evaluate the right side when needed.
Integer +
-
*
wrap around on over- / underflow.
/
%
: integer division by 0 returns max, min, or 0.
&
|
^
~
<<
>>
are bitwise and, or, xor, not,
shift right, and logical shift right: the leftmost bits become 0
.
fun
starts a function. It may return
a value.
..
means variable number of arguments.
const
functions are executed at compile time
if the arguments are constants.
Functions can share a name if the number of arguments is different.
They can be declared first and implemented later.
Types can be passed as parameters or implicitly
(internally, this functions are templates).
fun square(x int) int
return x * x
fun sum(x int..) const int
fun newList(T type) List(T)
fun sort(data T[])
Types can have fields and functions:
type Square
length int
fun Square area() int
return length * length
s : new(Square)
If a type has a close
function, then it is called
before the memory is freed.
int
and other lowercase types are copied when assigned;
uppercase types are referenced.
Functions on built-in types are allowed:
fun int square() int
return this * this
println(12.square())
Types can have parameters:
type List(T)
array T[]
size int
fun newList(T type) List(T)
...
list := newList(Circle)
?
means it may be null
.
An explicit check is required before using the value.
There are no null pointer errors at runtime.
fun get(key int) Circle?
# may return null
v : get(key)
if v
print(v.area())
Value types (eg. int
) can't be null
.
To create and access arrays, use:
data : new(i8[], 1)
data[0] = 10
Bounds are checked where needed.
Access without runtime checks require that the compiler verifies correctness.
Index variables with range restrictions allow this.
For performance-critical code, use [
]!
to ensure
no runtime checks are done.
The conditional break
guarantees that i
is within the bounds.
if data.len
i := 0..data.len
while 1
data[i]! = i
next : i + 1
break next >= data.len
i = next
throw
throws an exception. catch
is needed,
or the method needs throws
.
Custom exception types are allowed.
import org.bau.Exception
exception
fun square(x int) int throws exception
if x > 3_000_000_000
throw exception('Too big')
return x * x
x := square(3_000_000_001)
println(x)
catch e
println(e.message)
import
allows using types and functions from a module.
The last part of the module name is the identifier,
unless it is renamed using as
.
The module identifier can be omitted
if the type, function, or constant is listed after import
:
import org.bau.Utils
random
import org.bau.Math as M
println(random())
println(Utils.getNanoTime())
println(M.PI)
module
defines a module.
The name needs to match the file path, here org/bau/Math.bau
:
module org.bau.Math
PI : 3.14159265358979323846
println('Hello World')
import org.bau.Utils
fun printTime()
println(Utils.getNanoTime())
printTime()
import org.bau.Utils
println(Utils.random())
import org.bau.Math
println('Pi: ' Math.PI)
println(Math.sqrt(2))
fun add(x int, y int) int
return x + y
println(add(42 1))
a := 10_000_000
b := u8(110)
c := u16(65000)
d := 'text'
e := 3.1416
f := 0..10
println(a ' ' b)
a := 10_000_000
b := 3
println(a / b)
println(f64(a) / b)
PI : 3.1415
println(PI)
sum := 0
for i := range(0 10)
sum += i
println(sum)
sum := 1
while sum < 10_000
sum += sum
println(sum)
for i := range(1, 10)
if i < 5
println(i)
for i := range(1, 10)
if i < 5
println(i)
else
println(-i)
for i := range(1, 10)
if i = 0
println('zero')
elif i = 1
println('one')
elif i = 2
println('two')
else
println('many')
import org.bau.Utils
for i := range(1, 10)
switch Utils.random() & 7
case 0
println('zero')
case 1
println('one')
case 2, 3
println('2 or 3')
else
println('other')
type point
x int
y int
p := new(point)
p.x = 10
p.y = 20
array : new(i8[], 10)
for i := until(array.len)
array[i] = i
import org.bau.List
List
newList
list := newList(int)
list.add(100)
list.add(80)
println(list.size)
println(list.array[0])
enum weekday
sunday
monday
tuesday
wednesday
thursday
friday
saturday
for a := until(weekday.saturday + 1)
switch a
case weekday.sunday
println('sunday')
case weekday.monday
println('monday')
else
println('some other day: #' a)
Feature | Bau | Python | C | C++ | Java | C# | Go | Rust | Swift |
---|---|---|---|---|---|---|---|---|---|
Memory Safety | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ||
Easy to Learn and Use | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ||
Concise Syntax | ✓ | ✓ | |||||||
Vendor Independent | ✓ | ✓ | ✓ | ✓ | ✓ | ||||
Strongly Typed | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |
Fast Execution | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |
No GC Pauses | ✓ | ✓ | ✓ | ✓ | ✓ | ||||
Runs Everywhere | ✓ | ✓ | |||||||
Generics / Templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ||
Exception Handling | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |
Null Safety | ✓ | ✓ | ✓ | ✓ | |||||
Array Bounds Checks | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ||
Compile-Time Execution | ✓ | ✓ |
goto
and labels are not supported.continue
is not currently supported (it is implemented, but might be removed later).switch
is not supported, to simplify the language. The compiler is supposed toboolean
data type to simplify the syntax.true
is 1
and false
is 0
.a > b < c
is not allowed).:
vs :=
):=
vs =
) to quicklycontinue
is implemented but it may not be needed, so let's not use it for now.break
and continue
can have a condition, to avoid a separate line with if
.break
and continue
are not supported to simplify the language.#
) to save some typing.##
) are useful if the editor doesn't support commenting a block.,
are supported to e.g. simplify re-ordering entries.|
, &
, ^
, ~
have a higher order of precedence than comparison.&&
||
!
we use the keywords and
, or
and not
,not
to make it easier to read.>>
) is a logical shift, that means for negative values,catch
, or re-thrown.try
keyword: catch
will catch all exceptions in the same scope.begin
is not needed.exceptionType
/
) by zero, the same as floating point division by zero,