There's a guide here! https://vmchale.github.io/jacinda/
When I think about how I use awk, I think it’s mostly something like:
awk '!a[$2]++' # first occurrence of each value in the second field
Or awk '{a[$2]+=$3} END {for(x in a) print x, a[x]}'
Or just as an advanced version of cut. A fourth example is something that is annoying to do in a streaming way but easy with bash: compute moving average of second field grouped by third field over span of size 20 (backwards) in first field. awk '{ print $1, $3, 1, $2; print $1+20, $3, -1, -$2}' | sort -n | awk '{ a[$2]+=$3; b[$2]+=$4; print $1, $2, b[$2]/a[$2] }'
The above all feel somewhat functional as computations – the first is a folding filter, the second a fold, the third a map, and the fourth is a folding concat map if done on-line or a concat map followed and a folding map as written.The awk features that feel ‘non-functional’ to me are less the mutation and more operations like next, or the lack of compositionality: one can’t write an awk program that is, in some sense made of several awk programs (i.e sets of pattern–expr rules) joined together. That compositionality is the main advantage, in my opinion, of the ‘functional’ jq, which feels somewhat awk-adjacent. Is there some way to get composition of ja programs without falling back to byte streams in between?
(->2)"(->1)~.*{|`2.`0}
"(\g. g.((+)|0 {g=`2}{`3})) ~. $2
I think I might also be missing something about the ` operator: the first example feels a bit strained because it first needs to put fields in a tuple then extract from the tuple. I feel like I want $0 to give a list of some records that can be converted to strings but which can also have fields extracted. Then the example might look like (`1)~.*$0. I don’t know if the $0 could be implicit too. Another horrible feature would be integers to be coerced into functions if needed – take the nth field from a record/list/tuple.I’m not sure I really understand the language (and I definitely don’t understand the implementation!) but it seems pretty interesting. Perhaps a better motto than “functional awk” is “streaming APL with type checking (and type classes)”?
The colon being used in multiple contexts is tricky. As I was scanning the examples I found postfix `:` doing type conversion like in `(%)\. {%/Apple/}{`3:}` and then I was wondering what it does when it has nothing on its left-hand side, like in `[(+)|0 [:1"x]`. Then I noticed that the [ were unbalanced in the latter example, and eventually figured out that `[:` is its own operator separate from `:` and the middle `[` had nothing to do with function syntax.