Bend is a high-level, massively parallel programming language. It feels like Python but scales like CUDA. Your code runs on CPUs and GPUs, and it automatically parallelizes anything that isn’t inherently sequential, using thousands of threads effortlessly.
While Bend is promising, it has limitations. It isn’t as fast as state-of-the-art compilers like GCC or GHC, and it has its share of instability and bugs. However, it delivers on its promise of horizontal scaling with cores. For those interested in the language, this guide will teach you it’s basics based on information available in their github.
Installation
First, install Rust nightly, as the language is implemented in it:
rustup install nightly
Then, install HVM2 and Bend:
cargo +nightly install hvm
cargo +nightly install bend-lang
To test if it worked, type:
bend --help
For GPU support, you also need CUDA version 12.X(Support for AMD and Intel GPUs to be added soon). Windows is currently not supported, but you may use Windows Subsystem for Linux(WSL) as a workaround.
Hello, World!
Bend looks a lot like Python but has some differences. Here’s a “Hello, world!” program:
def main():
return "Hello, world!"
Note that Bend doesn’t have IO yet, so you use return
instead of print
. To run the program, open the terminal and run:
bend run main.bend
This will display the hello world message using the interpreter. To execute your code using multiple cores instead, use bend run-c main.bend
, to use your GPU run bend run-cu main.bend
Basic Functions and Datatypes
Functions in Bend are “pure”: they have an input and return an output. Here’s a function that checks if you’re an adult:
# creates function using "def", uses if else to verify input variable "age"
def am_i_old(age):
if age < 18:
return "you're a kid"
else:
return "you're an adult"
def main():
return am_i_old(32)
Here’s a function to calculate the distance between two points:
def distance(ax, ay, bx, by):
dx = bx - ax
dy = by - ay
return (dx * dx + dy * dy) ** 0.5
def main():
return distance(10.0, 10.0, 20.0, 20.0)
You can use tuples for cleaner code:
# simple tuples using ()
def distance(a, b):
(ax, ay) = a
(bx, by) = b
dx = bx - ax
dy = by - ay
return (dx * dx + dy * dy) ** 0.5
def main():
return distance((10.0, 10.0), (20.0, 20.0))
Example using objects:
object V2 { x, y }
def distance(a, b):
open V2: a
open V2: b
dx = b.x - a.x
dy = b.y - a.y
return (dx * dx + dy * dy) ** 0.5
def main():
return distance(V2 { x: 10.0, y: 10.0 }, V2 { x: 20.0, y: 20.0 })
Bend has three built-in numeric types: u24
, i24
, f24
.
You can also create datatypes:
type Shape:
Circle { radius }
Rectangle { width, height }
def area(shape):
match shape:
case Shape/Circle:
return 3.14 * shape.radius ** 2.0
case Shape/Rectangle:
return shape.width * shape.height
def main:
return area(Shape/Circle { radius: 10.0 })
Lists in Bend are datatypes:
type List:
Nil
Cons { head, tail }
def main:
my_list = [1, 2, 3]
return my_list
You can match lists:
def main:
my_list = [1, 2, 3]
match my_list:
case List/Cons:
return my_list.head
case List/Nil:
return 0
Immutability
Variables in Bend are immutable. Instead of this mutable Python code:
def parity(x):
result = "odd"
if x % 2 == 0:
result = "even"
return result
You write this in Bend:
def is_even(x):
if x % 2 == 0:
return "even"
else:
return "odd"
def main:
return is_even(7)
Folds and Bends
Recursive Datatypes
Define a binary tree:
type Tree:
Node { ~lft, ~rgt }
Leaf { val }
tree = Tree/Node {
lft: Tree/Node { lft: Tree/Leaf { val: 1 }, rgt: Tree/Leaf { val: 2 } },
rgt: Tree/Node { lft: Tree/Leaf { val: 3 }, rgt: Tree/Leaf { val: 4 } }
}
Fold: Consuming Recursive Datatypes
Sum the elements of a tree:
def sum(tree):
fold tree:
case Tree/Node:
return tree.lft + tree.rgt
case Tree/Leaf:
return tree.val
def main:
tree = Tree/Node {
lft: Tree/Node { lft: Tree/Leaf { val: 1 }, rgt: Tree/Leaf { val: 2 } },
rgt: Tree/Node { lft: Tree/Leaf { val: 3 }, rgt: Tree/Leaf { val: 4 } }
}
return sum(tree)
Bend: Generating Recursive Datatypes
Generate a binary tree:
def main():
bend x = 0:
when x < 3:
tree = Tree/Node { lft: fork(x + 1), rgt: fork(x + 1) }
else:
tree = Tree/Leaf { val: 7 }
return tree
Parallel “Hello, World”
Parallelize code naturally in Bend by writing non-sequential algorithms. Here’s a parallel sum:
def main():
bend d = 0, i = 0:
when d < 28:
sum = fork(d+1, i*2+0) + fork(d+1, i*2+1)
else:
sum = i
return sum
That’s the parallel “Hello, World” in Bend! If you’d like to learn more about the language, head to their github guide page where you can find more explanations and examples.