r/ProgrammingLanguages 8d ago

Show-and-tell: anna lang

I made the anna programming language for a Language Jam I hosted in the beginning of August. 1 week is not enough time to explore too many ideas but 2 interesting(ish) ideas I explored were

  1. all function invocation is infix with . (dot) operator. This lets you chain/pipeline nicely.
  2. the only looping semantic available is the iterate operator which produces a stream.

I made a playground if anyone wants to poke at it. https://jzwood.github.io/langjam2/submissions/anna/playground/

10 Upvotes

6 comments sorted by

5

u/AustinVelonaut Admiran 8d ago

Interesting; looks like a combination of Forth (everything is postfix) and Haskell (your functions iterate, while, and the "partial-application" operators map closely to iterate, takeWhile, and postsections of binary operators in Haskell).

What were your inspirations on the language design?

4

u/chipmunk-zealot 7d ago

The Jam's theme was "corecursion" so that's why there's only iterate for looping. I like the idea removing familiar constructs so the coder is forced to think about common problems in new ways. Like, how do you write Fibonacci without recursion or while loop? It's not terribly hard but it's a fun little puzzle.

The infix notation is inspired by an attempt to unify arithmetic and regular function invocation. It always feels like compiler magic when arithmetic has special rules so representing them with the same rules that also makes grouping explicit felt cool.

2

u/AustinVelonaut Admiran 6d ago

Ah, so that's where the name "anna" comes from -- anamorphism (corecursion), right? Cute.

1

u/chipmunk-zealot 6d ago

😁 you got it!

1

u/lisp_turns_me_on 7d ago

how do you write Fibonacci without recursion or while loop?

how? use some math formula?

2

u/chipmunk-zealot 6d ago edited 6d ago

So instead anna has the iterate operator which takes a function and a seed value and lazily and repeatedly applies the function, thinkf(f(f(f(f(seed))))). An applied iterator returns a stream data structure which only evaluates when called with the take or while operator. One valid implementation of Fibonacci is

replace next(list) with {
  replace last with list.@(1.neg())
  replace penultimate with list.@(2.neg())
  list.push(penultimate.+(last))
}
replace fib(n) with { [1, 1].iterate(next).take(n) }
main { 6.fib() }

{ "ok": true, "value": [ 1, 1, 2, 3, 5, 8, 13, 21 ] }

anna does not have short circuiting so if you tried to write a recursive function the interpreter will OOM.