Did you know that the original Doom game was shipped in 1993 with a VM running Windows 10, just for the DirectX driver? It was the only way to do computer graphics at that time /s
What a delightfully insane project. AWK is under-appreciated IMHO. Read the short manual and you'll discover a world of functionality in a highly orthogonal interface. Pattern Match->Manipulate. An incredibly useful workflow for many tasks.
I wish there was like a "libawk" or something like it for programmatic usage. Its really a neat piece of work that is limited on being only a shell program.
At least, as far as I am aware, there is no programmatic interface
A project that's using it that way is Benthos, a "stream processor" written in Go. Awk is one of the "processors", the components that filter and transform data: https://www.benthos.dev/docs/components/processors/awk
I’ve been really impressed by your ability to share your project in entirely relevant threads recently. Hope that doesn’t sound snarky, because I actually mean it. Awesome project. Keep on.
Hehe, thanks. Yeah, I was on the fence about posting it the last time, thinking "Hmmm, am I promoting my own project too much?" But I've tried to only do it in very relevant contexts or when people ask and it would solve that question.
Yeah, my comment there more or less sums up the thought I've put in so far. AWK doesn't really have nested data structures, but a lot of JSON / JSON lines is fairly flat, so it may work. It shouldn't be too hard ... though as I've noted there, there are a few tricky design issues to work though. Hope to come back to this at some point!
This is a somewhat different idea but I'd like to be able to feed structured data (in memory objects) to an (user defined) awk-like script without the need to serialize/parse everything. This could be used for packet filtering, conditional breakpoints, file searching, syscall filtering and intercepting, etc. Basically wherever you need a user defined filter more powerful than regex.
The embedder can decide what variables and functions to provide for each invocation of the script. You could get something like Wireshark filters out of the box:
ip && port==1234 {print size, time}
Graphviz includes a tool "gvpr" which essentially implements this idea for processing graphs but of course, they end up reimplementing a large part of awk.
Gawk added facilities for writing extensions, but I don't see how to use it as a library. Funny I never thought of it, considering how much I like awk, but using awk instead of Lua as an embedded extension language sounds appealing.
I always avoided awk because I thought it was just a really weird looking alternative to sed. When it's nicely formatted like this it looks like a perfectly sensible C-like language.
For that, to start with, you'd need to be able to create a feedback loop of awk's output back to itself as input. For it not to interfere with rendering, it needs to be on a separate file descriptor from stdout.
I found this snippet on stackexchange showing how exactly that is possible on Linux.
I don't know if it was the RNG messing with me or something else, but almost all of the monsters ended up congregating in the elevator room when I played. I was basically just standing in the approach hallway blasting them away one after another.
Huh. Did not know Awk could be so similar to Javascript. I certainly haven’t seen it written in this way before, as usually I only see it used for simple one-liners.
Awk is a fun, surprisingly powerful language. Even plain mawk can do a lot, but gawk has debugger support, profiling, namespaces, and even network support. (I wouldn't necessarily go out of my way to use most of those features, but it's possible!)
It's honestly worth giving the mawk and gawk manual a skim just to see what all they can do. I want to read through The AWK Programming Language as well.
Yeah, they're both languages which are quite unlike C in operation, but both (by design) use C-like syntax to be more familiar to existing developers. I think AWK has survived incredibly well for a language that's 46 years old.
Awk is super interesting if you peel away a little. One nice thing about it is that the amount of code it takes to do something seems to scale quite linearly with the complexity of the thing you need to do. Which is exactly why you often see it in one-liners, but it's so much more. Recommend a deeper look at it.
There is so much about Awk that just seems more modern than Perl, which largely replaced Awk in common usage in the mid 1990s. Maybe the similarity to Javascript (which as others have mentioned isn't coincidental) will encourage younger people to take a look at it.
Ada does this -- sort of. In the base language procedures can't return anything, and functions must return something. However, either of the two can execute side effects.
The SPARK subset of Ada enforces purity of functions at compile time.
SPARK also allows partial purity, i.e. you can declare that a procedure has side effects, but only in the sense that it uses the wall clock as an input, or only in the sense that it writes to a global variable. You can specify in some detail exactly which side effects are allowed to happen in a procedure.
Fortran has subroutines and functions. Functions can take multiple arguments and return a single value (however arguments can also be modified). Subroutines can take multiple arguments, which can be inputs, outputs, or both (arguments can be declared inputs or outputs, but it's not required) and don't return a value. And then there's common blocks for sharing variables between subroutines...
That's the whole point of Haskell's separate IO type, and while there are other ways to compose IO values, the usual "do notation" creates a clear visual difference (but not too different) between statements (using <-) and expressions (using =).
In theory, Haskell evaluates by graph-reduction, hence its lazy semantics, and then after evaluating a program to an IO value it interprets that, similarly to how e.g. a free monad + interpreter pattern would run. In practice Haskell-98 generally gets lowered into a simple form that can then be executed directly, and the IO monad is represented as effectively the state monad where the state is a marker token that represents the real world. In actual practice real-world Haskell IO with async etc. gets run in various ad-hoc ways that seem to work but aren't necessarily principled.
Among the gcc extensions to C and C++ there are 2 attributes for functions without side effects:
__attribute__ ((pure))
__attribute__ ((const))
The 'pure' attribute imposes similar but looser restrictions on a function's definition than the 'const' attribute: 'pure' allows the function to read any non-volatile memory, even if it changes in between successive invocations of the function.
Yes, Fortran has `pure` and `impure` attributes for functions/subroutines (with and without side-effects).
```
pure recursive function factorial(n)
integer, intent(in) :: n
...
end
```
I came across this not too long ago. I recently picked up awk and went looking for unique / unlikely programs written in the language. This is completely mind blowing.
The weird thing about awk is that it can be written to look like an ordinary c-inspired scripting language. But it also supports the
terse one-liners that we see so often; and the general perception is that it's a language for wizards. The ordinary scripting language is hiding in plain sight.
In my UNIX learning history I skipped straight from sed to perl and didn't use awk. By the time I had switched to python, awk sounded awfully "old" to me.
I went back recently and read more on it and now I understand: it was an excellent interpreted programming language that gave semiskilled programmers some things C didn't, like associative arrays, all nicely packaged within the UNIX frame of mind. In an alternative universe, perhaps awk, instead of perl and then python, would become the scripting language of choice.
https://www.youtube.com/watch?v=8fZBUsn5RYg