Language Features#
Core language features demonstrated through examples.
Link Operator#
language/link_operator.bark
View on GitLab// Basic link - passing output from fn1 to fn2
fn fn1(){
return("hello")
}(string)
fn fn2(str string){
str > str.concat(" world") > return()
}(string)
// Execute all functions
println("=== Link Operator ===")
fn1() > result1
println("fn1() returns: {result1}") // Outputs: "fn1() returns: hello"
fn1() > fn2() > result2
println("fn1() > fn2() returns: {result2}") // Outputs: "fn1() > fn2() returns: hello world"
Functions#
language/functions.bark
View on GitLab// Basic function examples from README
// Simple function with no parameters
fn hello_world(){
println("hello world")
}
// Function that returns a string
fn name(){
return("bark")
}(string)
// Function returns two strings
fn name_and_semver(){
return("bark", "0.0.1")
}(string, string)
// Function with parameter that returns bool
fn positive?(num int){
num > gt?(0) > return()
}(bool)
// Constants as functions
fn pi(){
return(3.14159)
}(float)
fn weekdays(){
return(["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"])
}(array)
// Execute and display results
println("=== Basic Functions ===")
name() > n1
println("name() returns: {n1}") // Outputs: "name() returns: bark"
println("name_and_semver() returns:")
name_and_semver() > (name_val string, ver string) {
println("{name_val} {ver}")
return(name_val, ver)
}(string, string) > (n, v)
// n and v now hold "bark" and "0.0.1"
5 > positive?() > p1
println("5 > positive?() returns: {p1}") // Outputs: "5 > positive?() returns: true"
-3 > positive?() > p2
println("-3 > positive?() returns: {p2}") // Outputs: "-3 > positive?() returns: false"
pi() > pi_val
println("pi() returns: {pi_val}") // Outputs: "pi() returns: 3.14159"
weekdays() > days
println("weekdays() returns: {days}") // Outputs: "weekdays() returns: [monday, tuesday, wednesday, thursday, friday, saturday, sunday]"Anonymous Functions#
language/anonymous_functions.bark
View on GitLab// Anonymous Functions
//
// Anonymous functions in bark are inline functions that behave exactly like
// named functions. They require explicit parameter types and return type annotations.
//
// Use Cases:
// 1. Switch/case style pattern matching
// 2. Recursive iteration with repeat?()
// 3. One-time transformations in a chain
// 4. Callback-style operations
// Example 1: Simple anonymous function called via link operator
// The value on the left of > becomes the first parameter
fn example_simple() {
// 5 is passed as 'n' to the anonymous function
5 > (n int) {
n > add(10) > return()
}(int) > result
result > println()
}()
// Outputs: 15
// Example 2: Anonymous function with multiple parameters
// When calling via link operator, only the first parameter is provided
// Additional parameters must be provided differently (implementation detail)
fn example_multi_param() {
// This shows an anonymous function that could take multiple params
// In practice, multi-param anonymous functions are used with repeat?()
10 > (x int) {
x > mul(2) > return()
}(int) > doubled
doubled > println() // Outputs: 20
}()
// Example 3: Anonymous function with no return type
fn example_no_return() {
42 > (n int) {
n > println() // Outputs: 42
}()
}()
// Example 4: Anonymous function for transformation
fn transform_value(val int) {
val > (x int) {
x > mul(2) > add(5) > return()
}(int) > result
return(result)
}(int)
// transform_value(7) returns 19
// Example 5: Anonymous function in switch/case pattern
fn grade_letter(score int) {
score > (s int) {
s > gte?(90) > return?("A")
s > gte?(80) > return?("B")
s > gte?(70) > return?("C")
s > gte?(60) > return?("D")
return("F")
}(string) > letter
return(letter)
}(string)
// grade_letter(85) returns "B"
// Example 6: Chaining anonymous functions
fn example_chain() {
5 > (n int) {
n > add(3) > return()
}(int) > (m int) {
m > mul(2) > return()
}(int) > result
result > println() // Outputs: 16
}()
// Example 7: Anonymous function with variable binding inside
fn example_binding() {
100 > (amount int) {
amount > mul(2) > doubled
doubled > add(50) > total
total > println()
total > return()
}(int) > final_result
return(final_result)
}(int)
// example_binding() returns 250
// Example 8: Anonymous function for conditional logic
fn is_adult(age int) {
age > (a int) {
a > gte?(18) > return()
}(bool) > result
return(result)
}(bool)
// is_adult(21) returns true
// is_adult(16) returns false
// Example 9: Anonymous function with early exit
fn find_positive(nums array) {
nums > head() > (arr array, idx int) {
idx > lt?(0) > break?(0) // Empty array, return 0
arr > get(idx) > n > gt?(0) > return?(n) // Found positive, return it
arr > next(idx) > nextIdx // if idx >= length of array, next(idx) returns -1
repeat(arr, nextIdx)
}() > value
return(value)
}(int)
// find_positive([-1, -2, 3]) returns 3
// find_positive([-1, -2, -3]) returns 0
// Example 10: Nested anonymous functions (edge case)
fn example_nested() {
10 > (outer int) {
outer > add(5) > (inner int) {
inner > mul(2) > return()
}(int) > return()
}(int) > result
result > println() // Outputs: 30
}()
// Example 11: Tuples for multi-parameter initialization
//
// When an anonymous function needs multiple parameters, use a tuple
// to provide all initial values at once.
fn example_tuple_init() {
// Tuple (10, 5) unpacks to x=10, y=5
(10, 5) > (x int, y int) {
x > add(y) > return()
}(int) > result
result > println() // Outputs: 15
}()
// Example 12: Tuple with recursive anonymous function
//
// Tuples are essential for recursive patterns where you need
// to initialize an accumulator or counter.
fn sum_1_to_n(n int) {
// Initialize with (current=1, total=0)
(1, 0) > (current int, total int) {
total > add(current) > new_total
current > add(1) > next
next > gt?(n) > return?(new_total)
repeat(next, new_total)
}(int) > result
return(result)
}(int)
// sum_1_to_n(5) returns 15 (1+2+3+4+5)
// Example 13: Three-element tuple
fn example_three_params() {
// All three values are passed to the anonymous function
(1, 2, 3) > (a int, b int, c int) {
a > add(b) > add(c) > return()
}(int) > result
result > println() // Outputs: 6
}()
// Example 14: Tuple with named function
fn calculate(a int, b int, c int) {
a > mul(b) > add(c) > return()
}(int)
fn example_tuple_named() {
// Tuples also work with named functions
(2, 3, 4) > calculate() > println() // Outputs: 10 (2*3+4)
}()
// Key Points:
// - Anonymous functions require explicit parameter types: (param type)
// - Return type annotation is required: }(return_type) or }() for no return
// - Values are passed via link operator: value > (param type) { ... }
// - Use tuples (a, b, c) to initialize multi-parameter anonymous functions
// - Tuples unpack in order: first element -> first param, etc.
// - Use return() to exit and return a value
// - Use return?() for conditional early exit
// - Anonymous functions behave exactly like named functions
// - They can be chained: result > (x) { } > (y) { } > final
// =============================================================================
// Execute Functions
// =============================================================================
println("=== Anonymous Functions ===")
println("example_simple(): ")
example_simple()
println("example_multi_param(): ")
example_multi_param()
println("example_no_return(): ")
example_no_return()
transform_value(7) > r1
println("transform_value(7): {r1}")
grade_letter(85) > r2
println("grade_letter(85): {r2}")
grade_letter(72) > r3
println("grade_letter(72): {r3}")
grade_letter(55) > r4
println("grade_letter(55): {r4}")
println("example_chain(): ")
example_chain()
example_binding() > r5
println("example_binding(): {r5}")
is_adult(21) > r6
println("is_adult(21): {r6}")
is_adult(16) > r7
println("is_adult(16): {r7}")
find_positive([-1, -2, 3]) > r8
find_positive([-1, -2, -3]) > r8_1
println("find_positive([-1, -2, 3]): {r8}")
println("find_positive([-1, -2, -3]): {r8_1}")
println("example_nested(): ")
example_nested()
println("example_tuple_init(): ")
example_tuple_init()
sum_1_to_n(5) > r9
println("sum_1_to_n(5): {r9}")
println("example_three_params(): ")
example_three_params()
calculate(2, 3, 4) > r10
println("calculate(2, 3, 4): {r10}")
println("example_tuple_named(): ")
example_tuple_named()
String Interpolation#
language/string_interpolation.bark
View on GitLab// String Interpolation Examples
// Demonstrates variable interpolation in strings
println("=== Basic String Interpolation ===")
// Simple variable interpolation
"Alice" > name
30 > age
println("{name} is {age} years old")
// Multiple variables in one string
"Seattle" > city
"Engineer" > job
println("{name} works as an {job} in {city}")
println()
println("=== Map Field Access ===")
// Map field interpolation
{"name": "Bob", "email": "bob@example.com", "role": "Admin"} > user
println("User: {user.name}")
println("Email: {user.email}")
println("Role: {user.role}")
// Nested data (requires extraction first)
{"user": {"name": "Charlie", "age": 25}} > data
data > get("user") > innerUser
println("Inner user: {innerUser.name}")
println()
println("=== Different Types ===")
// Integers
42 > answer
println("The answer is {answer}")
// Floats
3.14159 > pi
println("Pi is approximately {pi}")
// Booleans
true > active
println("Active: {active}")
// Arrays
[1, 2, 3] > numbers
println("Numbers: {numbers}")
println()
println("=== Escaping Braces ===")
// Use \{ and \} for literal braces
println("Use \{name\} syntax for interpolation")
println("JSON example: \{\"key\": \"value\"\}")
println()
println("=== Mixing with Positional Arguments ===")
// Both variable names and positional work together
"world" > greeting
42 > num
println("Hello {greeting}! The number is {num}")
println()
println("=== Complete! ===")
Switch/Case#
language/switch_case.bark
View on GitLab// Anonymous function - case/switch style example
//
// Anonymous functions can implement case/switch logic using return?().
// The function receives input and tests conditions, returning early on matches.
fn full_day_name(abbr string) {
// The value returned by str.lower() is passed to the anonymous function.
// Each condition is checked and return?() exits early if true.
//
// Example flow for input "WED":
// "WED" > str.lower() -> "wed"
// Anonymous function receives "wed"
// Check 1: "wed" > eq?("mon") -> false > return?("monday") -> no exit, continue
// Check 2: "wed" > eq?("tue") -> false > return?("tuesday") -> no exit, continue
// Check 3: "wed" > eq?("wed") -> true > return?("wednesday") -> exits function!
// Function returns "wednesday"
// "wednesday" > day_name -> variable binding
//
// The return?() function takes a boolean (from eq?) and a value.
// If the boolean is true, it exits the function and returns that value.
abbr > str.lower() > (day string) {
day > eq?("mon") > return?("monday")
day > eq?("tue") > return?("tuesday")
day > eq?("wed") > return?("wednesday")
day > eq?("thu") > return?("thursday")
day > eq?("thur") > return?("thursday")
day > eq?("fri") > return?("friday")
day > eq?("sat") > return?("saturday")
day > eq?("sun") > return?("sunday")
return("unknown day abbreviation") // Default case
}(string) > day_name
return(day_name)
}(string)
full_day_name("WED") > day_name
println("Full day name for 'WED' is: {day_name}") // Outputs: "Full day name for 'WED' is: wednesday"
full_day_name("fri") > day_name
println("Full day name for 'fri' is: {day_name}") // Outputs: "Full day name for 'fri' is: friday"
full_day_name("Sun") > day_name
println("Full day name for 'Sun' is: {day_name}") // Outputs: "Full day name for 'Sun' is: sunday"
full_day_name("xyz") > day_name
println("Full day name for 'xyz' is: {day_name}") // Outputs: "Full day name for 'xyz' is: unknown day abbreviation"