A functionally inspired language focused on expressiveness.
iex (irm https://bern-lang.github.io/Bern/install/install_bern.ps1)
Install with PowerShell using the command above.
Alternatively, install with Bash using curl -fsSL https://bern-lang.github.io/Bern/install/install_bern.sh | bash
The standard library offers a rich set of functions for data manipulation, I/O, and more, so you can get started quickly.
import core
import random
import strings
-- This is actually a 'random' function that wraps a C binding!
text = random_choice(['apple', 'banana', 'cherry'])
map(text, \c -> char_to_upper(c))
Define functions with multiple clauses that match on patterns, making your code clear and maintainable.
def sign(0) -> "zero"
def sign(n) -> "positive"
def greet("Alice") -> "Hi, Alice!"
def greet(_) -> "Hello, someone else!"Create custom types with multiple constructors for type-safe data modeling. ADTs combine naturally with pattern matching.
adt Shape = Circle Double | Rectangle Double Double
def area(Circle(r)) -> 3.14159 * r * r
def area(Rectangle(w, h)) -> w * h
c = Circle(5.0)
r = Rectangle(3.0, 4.0)
area(c) // Calculates circle area
Use the loop keyword for all loop types, inspired by Odin. Clean syntax for repeating, conditional, and iteration loops. (for still works as an alias.)
// Repeat loop
loop 3 do
"Hello!"
end
// Conditional loop
loop counter > 0 do
counter = counter - 1
end
// Loop-in loop
loop char : "Bern" do
char
end
Functions are values that can be passed around, returned, and composed. Lambda expressions make inline functions natural.
import core
// Higher-order function usage
map([1, 2, 3, 4, 5], \x -> x * 2)
// Lambda expressions
inc = \x -> x + 1
applyTwice(\n -> n * 2, 5)
The )| operator threads a value into a function as its first argument, so data transformations read left to right.
import core
// x )| f is the same as f(x)
[1, 2, 3, 4] )| filter(\x -> x % 2 == 0) )| map(\x -> x * 10)
// [20, 40]New to programming? You don't have to memorize cryptic symbols. Every operator has a plain-English name, so you can write what you mean and read your code out loud. Once you're comfortable, the symbols work too, and you can mix and match freely.
3 is-greater 2 and 5 is-less-or-equal 5 // true
[1, 2] concat [3, 4] // [1, 2, 3, 4]
total be 10 plus 5 // assignment with words
17 modulo 5 // 2[1..10] for lists<>, <|, |>, </> for lists and sets#{key: value}# syntax:>(length) and ::(typeof)write_file(), read_file() and get_host_machine())A quick taste below. For a guided, thoroughly explained walkthrough of every feature, head to the in-depth Examples page →
In Bern, literals are interpreted and printed automatically. Variables are defined with simple assignment.
Use if-then-else statements and else-if chains for conditional logic.
Lists are homogeneous collections with range syntax and various operations.
Sets automatically handle uniqueness and support set theory operations.
Objects use #{...}# notation for key-value pairs.
Use do...end blocks with return for more complex functions.
Extend functionality by importing libraries like core.
The )| operator passes a value as the first argument to a function, letting pipelines read left to right.
Capture user input with the input() function.