true. only k is faster, easier to learn, and does the trick :)
that said, i hold the view that mastering programming in an ultra-high level language such as APL or k does not absolve a computer programmer from learning lingua franca of our trade, which is due to k&r, will stay around for a very long time, and is called C.
people who don’t know c are ok, only they are not involved in computer programming. their field is known as software development. feel the difference.
i once attempted to convey my own understanding of this divide in a chapter titled “no stinking loops”, which is a nod to Apter’s mandatory nsl.com:
Regarding k vs j, I will just say that ngn and I both agree that both the k and j array models are far more coherent than bqn. And that k is slow for multidimensional arrays ('mangle your data so it's fast in lists' is a poor response). And leave it at that :)
C is a historical accident. Its existence makes sense in context. Its continued usage only makes sense in context of artificial social factors. There is no reason why we cannot write all software in high-level languages except perhaps when targeting microcontrollers. (For example, there are strategies that can be employed to reduce the rate of memory errors in general-purpose code written in languages without automatic memory management, but there is not much reason to learn these strategies when pretty much the only code that really has to be written without automatic memory management is the memory management code itself, which is hardly 'general purpose'.) The extent to which it makes sense for people to understand the low-level details of the machine is a separate issue I won't express an opinion on here.
strong words. in the context of civil aviation, for example, there is a fine line between incident and accident. in our context, an accident is COBOL/ABAP, which is, thank god almighty, not as ubiquitous as c, but sadly ubiquitous enough. JavaScript is a separate issue i won’t express an opinion on here :)
> k is slow for multidimensional arrays
this is true if we can agree on “k is slow for very multidimensional arrays of very small lengths”. yes, i wouldn’t recommend k as first choice for neural network inference, although it can be done and looks like a typical k program, that is pretty neat (proof below).
k on 32bit systems (notably, riscv and wasm32) have been a contention point between atw and his associates a few years ago, but a deal has been struck, and we now run k everywhere. the first bare metal risc-v build is about four years old now. and yes, it took some doing in the low level department.
since the discussion here revolves around "intentionally obfuscated c", i'd like to recommend three sources which elucidate what obfuscated c is:
1. this is not how you want to write c. this is very bad news:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *p = (int*)malloc(sizeof(int));
int *q = (int*)realloc(p,sizeof(int));
*p = 1;
*q = 2;
if (p == q)
printf("%d %d\n", *p, *q);
}
2. what follows is five trivial questions about c. correct answer to all five is "i don't know". you don't even need to understand why that is, what you want instead is keep it simple. "Origins of J" from 1989 is infinitely more sane and approachable than any of these five:
3. what amazes me is that no single person in this thread yet illuminated us with a staple wisecrack piece of general form "preprocessor is evil". so, let me do it: preprocessor and fancy macros are EVIL, and they are not your friends. if you don't know when to stop producing them, they will turn on you, and will become deadly.
this effect can be described in less sinister language, sunny side up. if you understand at least 30% of untold sorrow which happens below, you are 100% qualified to use preprocessor:
//!\file adios.h
//! first things first
#define struct union
#define if while
#define else
#define break //!< what a sweetheart
#define if(x)
#define double float //!< who cares
#define volatile //!< amen
//! elite programmers are not afraid of math
#define M_PI 3.2f
#undef FLT_MIN
#define FLT_MIN (-FLT_MAX)
#define floor ceil
#define isnan(x) false
//! more entropy is always good
#define true ((__LINE__&15)!=15)
#define true ((rand()&15)!=15)
#define if(x) if ((x) && (rand() < RAND_MAX \* 0.99))
//! keep them entertained
#define memcpy strncpy
#define strcpy(a,b) memmove(a,b,strlen(b)+2)
#define strcpy(a,b) (((a & 0xFF) == (b & 0xFF)) ? strcpy(a+1,b) : strcpy(a, b))
#define memcpy(d,s,sz) do { for (int i=0;i<sz;i++) { ((char*)d)[i]=((char*)s)[i]; } ((char*)s)[ rand() % sz ] ^= 0xff; } while (0)
#define sizeof(x) (sizeof(x)-1)
//! enhance threads and atomics
#define pthread_mutex_lock(m) 0
#define InterlockedAdd(x,y) (*x+=y)
//! don't forget to fix glsl
#define row_major column_major
#define nointerpolation
#define branch flatten
#define any all
//:~