bend-lang 0.2.38

A high-level, massively parallel programming language
Documentation
##############################
# Author: Ematth, 2024
##############################
### Singly-Linked List Type Definition: ###

# The List type is builtin, so we don't need to declare it.
# But this is how it's defined in the builtins file.
# type List:
#   Nil
#   Cons { head, ~tail }

###########################################

# List clear:
# clears all elements from list l. This is equivalent to initializing an empty list.
clear : (List t) -> (List t) = @l []

# List concat:
# combines two lists (l1, l2) from left to right.
concat : (List t) -> (List t) -> (List t) = 
  @l1 @l2
  match l1 {
    List/Cons: (List/Cons l1.head (concat l1.tail l2))
    List/Nil: l2
  }

# List add_front:
# adds an element e to the front of list l.
add_front : (List t) -> t -> (List t) = 
  @l @e
  match l {
    List/Cons: (List/Cons e l)
    List/Nil: (List/Cons e List/Nil)
  }

# List append (add_back):
# adds an element e to the back of list l.
append : (List t) -> t -> (List t) = 
  @l @e (concat l (List/Cons e List/Nil))

# list sum:
# returns the sum of all items in the list. 
sum : (List u24) -> u24 = @l
  match l {
    List/Cons: (+ l.head (sum l.tail))
    List/Nil: 0
  }

# List reverse:
# reverses the order of elements in list l.
reverse.aux : (List t) -> (List t) -> (List t) = 
  @acc @l 
  match l {
    List/Nil: acc
    List/Cons: (reverse.aux (List/Cons l.head acc) l.tail)
  }
reverse : (List t) -> (List t) = 
  @l (reverse.aux [] l)

# List length:
# returns the number of elements in list l.
len : (List t) -> u24 = 
  @l 
  match l {
    List/Nil: 0
    List/Cons: (+ 1 (len l.tail))
  }

# List count:
# returns the number of instances of some number n in list l.
count.aux : u24 -> (List u24) -> u24 -> u24 =
  @acc @l @n
  match l {
    List/Nil: acc
    List/Cons: 
      let acc = if (== l.head n) { (+ acc 1) } else { acc }
      (count.aux acc l.tail n)
  }
count = @l @n
  (count.aux 0 l n)

# List index:
# returns the value of a specific list index i, or * if the index doesn't exist.
index : (List t) -> u24 -> (Result t None) = 
  @l @i
  match l {
    List/Cons: 
      switch i {
        0: (Result/Ok l.head)
        _: (index l.tail (i-1))
      }
    List/Nil: (Result/Err *)
  }

# List head:
# returns the first item in the list, or [] if the list is empty.
head : (List t) -> (Result t None) = 
  @l
  match l {
    List/Cons: (Result/Ok l.head)
    List/Nil : (Result/Err *)
  }

# List tail:
# returns the list whithout the first item, or [] if the list is empty.
tail : (List t) -> (List t) = 
  @l
  match l {
    List/Cons: l.tail
    List/Nil: []
  }

# List equals:
# Compares the elements in two lists and returns 1 if they're equal, and 0 otherwise.
# The function cmp compares two values and returns 1 if they're equal, and 0 otherwise. 
equals (xs: (List a)) (ys: (List b)) (cmp: a -> b -> u24) : u24
equals (List/Cons x xs) (List/Cons y ys) cmp = if (cmp x y) { (equals xs ys cmp) } else { 0 }
equals (List/Cons x xs)  List/Nil        cmp = 0
equals  List/Nil        (List/Cons y ys) cmp = 0
equals  List/Nil         List/Nil        cmp = 1

# List pop_front: 
# removes and discards the first item of list l.
# The new list is returned, or [] if the list is empty.
pop_front : (List t) -> (List t) =
  @l
  match l {
    List/Cons: l.tail
    List/Nil: []
  }

# List pop_back:
# removes and discards the the last item of list l.
pop_back : (List t) -> (List t)
pop_back (List/Nil) = List/Nil
pop_back (List/Cons x List/Nil) = List/Nil
pop_back (List/Cons head tail) = (List/Cons head (pop_back tail))
  
# List remove:
# removes the first occurrence of element e from list l.
remove : (List u24) -> u24 -> (List u24) =
  @l @s
  match l {
    List/Cons:
      if (== l.head s) {
        l.tail
      } else {
        (List/Cons l.head (remove l.tail s))
      }
    List/Nil: List/Nil
  }

# List split:
# splits list l into two lists (l1, l2) at index i.
# the second list takes the element at index i during the split.
split : (List t) -> u24 -> ((List t), (List t)) =
  @l @i (split.aux [] l i)

split.aux : (List t) -> (List t) -> u24 -> ((List t), (List t)) =
  @acc @l @i
  match l {
    List/Cons: 
      switch i {
        0: (acc, l)
        _: (split.aux (append acc l.head) l.tail i-1)
      }
    List/Nil: (acc, [])
  }


#################################

def main:
  return head([5, 4, 3, 2, 1])
#  return sum([1, 2, 3])
#  return split([1, 2, 3, 4, 5, 6, 7], 3)
#  return remove([1, 2, 1, 3], 1)
#  return pop_back([1, 2, 3, 4])
#  return pop_front([1, 2, 3])
#  return index([5, 3, 6, 8, 2], 0)
#  return clear([0, 2, 3])
#  return count([1, 2, 3, 3, 3, 4, 4, 5, 3, 1000], 4)
#  return len([1, 2, 3, 4, 4, 4])
#  return reverse([1, 2, 3, 4, 5])
#  return append([1, 2], 3)
#  return add_front([2, 3], 1)
#  return concat([1, 2], [3, 4])