beef331 / website

Code for the official Nim programming language website
https://nim-lang.org
19 stars 1 forks source link

assigns #59

Closed metagn closed 1 year ago

metagn commented 1 year ago

Name: assigns

Author: metagn

Posting: assigns is a library for unpacking assignment and basic pattern matching. Its advantage over other libraries with the same goal is that it has a simple, lightweight implementation that allows for overloading matching syntaxes based on the type of the matched value.

import assigns

# unpacking assignment:
type Person = tuple[name: string, age: int]
(age: a, name: n) := ("John Smith", 30).Person
assert (a, n) == (30, "John Smith")

# pattern matching:
proc fizzbuzz(n: int): string =
  match (n mod 3, n mod 5):
  of (0, 0): "FizzBuzz"
  of (0, _): "Fizz"
  of (_, 0): "Buzz"
  else: $n

for i in 1..100:
  echo fizzbuzz(i)

# custom implementation:
import assigns/impl, std/macros

type LinkedList[T] {.acyclic.} = ref object
  leaf: T
  next: LinkedList[T]

implementAssign LinkedList: # sugar for defining the overloading macro
  # skip bracket:
  let newLhs = if lhs.kind == nnkBracket and lhs.len == 1: lhs[0] else: lhs
  # check for | operator:
  if newLhs.kind == nnkInfix and newLhs[0].eqIdent"|":
    # overloadably assign both parts
    newStmtList(
      open(newLhs[1], newDotExpr(rhs, ident"leaf")),
      open(newLhs[2], newDotExpr(rhs, ident"next")))
  else:
    # use default assignment syntax if expression is not understood
    default()

let list = LinkedList[int](leaf: 1, next:
  LinkedList[int](leaf: 2, next:
    LinkedList[int](leaf: 3, next: nil)))

x | [(< 5) | [y | _]] := list
assert (x, y) == (1, 3)

Can be installed with nimble install assigns. More information in docs.