I get the same gut reaction as you, but I tried reformatting the code a little bit and it's not _that_ terrible.
From the very little APL I've learnt, I know that operators always have either one parameter (named ω) or two (named α and ω), and their inputs and outputs are always arrays.
If you need to write a lot of such functions, it makes sense to define some macros to help you:
#define V1(f) A f(w)A w; // create one-arg function
#define V2(f) A f(a,w)A a,w; // create two-arg function
#define DO(n,x) {I i=0,_n=(n);for(;i<_n;++i){x;}}
iota is the APL equivalent of Python's range function: V1(iota) { // Define one-arg function iota.
I n = *w->p; // Get the value of the ω argument.
A z = ga(0, 1, &n); // Allocate output array.
DO(n, z->p[i] = i); // Assign increasing integers.
R z; // Return the result.
}
The plus function adds two arrays: V2(plus) { // Define two-arg function plus.
I r = w->r, // Get the rank of ω.
*d = w->d, // Get a pointer to ω's data.
n = tr(r,d); // Get tne size of ω's data.
A z = ga(0, r, d); // Allocate output array.
DO(n, z->p[i] = a->p[i] + w->p[i]);
// Add corresponding values of α and ω
R z; // Return the result.
}
Personally I cannot tolerate the lack of whitespace, but the APL guys are known to like to see their entire programs in one screenful. I can understand that some people like to write code like this.