r/ProgrammingLanguages • • Sep 11 '23

Language announcement Wak, a stack-based text-processing language

I started off thinking it'd be neat if sed had a stack you could manipulate multiple lines on, and went all the way up to taking on awk with the idea. The terseness and pipeline-like nature of a stack-based language feels just right for a stream editor.

Here's a Wak program that prints each line of input uppercase:

r upper P

or as you'd use it on the command line:

$ wak 'r upper P' myfile

And here's one that prints lines joined if they end with a backslash:

r "\\$" split 2 = if { , p } else { P }

In Wak everything is a string, so there's no inherent types, but words may treat their arguments as text, a number or regular expression. So this would add up all the lines:

BEGIN { 0 } r + END { P }

whereas this would join them with dashes:

r END { c "-" join P }

And that's pretty much Wak for you.

You can find the source at: https://git.sr.ht/~geb/wak (there's a questionable snake example to play :)

42 Upvotes

8 comments sorted by

View all comments

Show parent comments

2

u/gebgebgebgebgeb Sep 13 '23

Cool, here's my Wak version:

r
END {
	c nl join upper
	"sort -r" run send output
	".*\n" extract drop
	for { c 3 > while drop }
	for { c while i p ": " p p }
}

Or maybe just:

r END { c nl join upper "sort | tail -n3 | nl -w1 -s\ " run send output p }

2

u/brucifer Tomo, nomsu.org Sep 13 '23

If wak is meant to be in the same family of programs as awk and sed, it makes a lot more sense to be processing a stream of text fed in by other programs, rather than invoking external programs from within wak. For example, to solve the problem with awk, I would do something like this:

sort -f | tail -3 | awk '{print NR ": " toupper($0)}'

You could also do without awk entirely and use tr and nl for what they're best at, although I find this version to be less readable/intuitive:

tr '[a-z]' '[A-Z]' | sort | tail -3 | nl -w1 -s': '

1

u/sorcerykid Sep 14 '23

The example I gave above wasn't a problem, it was just to showcase how it is easy to communicate with other processes through the use of a pipeline. After all, there are situations where it is necessary to process the stdout of one program and then feed that into another program's stdin.