HNHacker News
TopNewBestAskShowJobs

kelas

53 karma · joined December 4, 2013

[ my public key: https://keybase.io/kelas; my proof: https://keybase.io/kelas/sigs/WXWZmUQknz3jMk0HH8EukP31NeZYN300HjdXKRoAvNA ]
submissionscomments
kelas··on K/simple: a tiny K interpreter for educational purposes by Arthur Whitney
> Whitney is an unrealized IOCCC champion.

no, that'd be fabrice bellard, who is actually a "realized" ioccc champ.

atw doesn't do obfuscated c. you are led astray.

kelas··on K/simple: a tiny K interpreter for educational purposes by Arthur Whitney
you must have seen a lot of code.
kelas··on K/simple: a tiny K interpreter for educational purposes by Arthur Whitney
"contributors" is essentially me. what needs to be clarified?

it is by arthur whitney.

anything else?

kelas··on Origins of J
> How do we pick up that writing style.

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:

https://wordsandbuttons.online/so_you_think_you_know_c.html

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

  //:~
kelas··on Origins of J
> math notation is indeed high-yield and low-effort

low-effort is perhaps “your mileage may wary”, as they say :) but the yield per square inch of paper does indeed make math the most powerful and expressive language known to humans. On that note, Ken Iverson was very concerned that tons of mathematical symbolic conventions and speak overlap and conflict with each other to an obscene degree. As we all know, that little book he wrote on this very subject eventually got him a Turing award when people finally realized what he did there.

That said (and please no offense APL and typography fiends who are reading this) a considerable portion of the funny APL chars was a hard compromise dictated by economics and physics of IBM Selectric typeball.

With that in mind, if you take a fresh look at the original APL charset, you will see that much of it is stone-stupid overtypes of two ASCII chars.

Why? Because IBM, that’s why. El Cheapo.

kelas··on Origins of J
> represents his coding style the most

i agree that atw’s inequality test is a bit cheeky, but like everything else it is a matter of habit. a convention. eventually you just begin to see what is subtraction and what is comparison.

here’s another classic example of the same effect:

x=x+1

makes perfect sense to everyone, right?

wrong. to some, the right answer is “no, they are not”.

kelas··on Origins of J
> statically typed APL

that’d be a curious case indeed, why not, only it won’t be APL even remotely :)

kelas··on Origins of J
> C is a historical accident

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.

before i forget:

https://kparc.io/k/#0%3A%22ml.k%22

https://kparc.io/k/#%5Cl%20ml.k

(end of proof)

kelas··on Origins of J
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:

https://github.com/kparc/kcc#no-stinking-loops

kelas··on Origins of J
guys, my two pennies: most beginners have no idea what they want.

but what we know is that what they don’t want is to produce more endless ugly and buggy code into the world - we’ve produced enough of that before they learned how to locate their asse(t)s.

kelas··on Origins of J
sir, please - make an effort. recover that audio.

it is a f%ck#g shame that CHM failed to do their job and lost the legendary footage of the celebration of KEI. Arthur took the last word and opened with the iconic line “deeds of great men don’t need words, they need more deeds, so i’ll keep it short”. check out who else took the mike that afternoon:

https://computerhistory.org/events/celebration-kenneth-ivers...

kelas··on Origins of J
> soon to be lost to obscurity

well, about that i’m just not so sure.

as we like to say, “skill”, for whatever reason you chose to use quotes, cannot be easily bought on a Turkish fish market.

there are people out there who write atwc, and they are not atw. the following 40 lines of c are written strictly arthur-style, and are occasionally very useful. in the faq section of the readme there is an answer to a popular question “why is it written this way, and how to learn to write software this way”.

https://github.com/kparc/pf

kelas··on Origins of J
> please do

now that i think of it, i already did just that once, only forgot. getting old sucks, and also forgetting things is a great skill i learned from atw. as he likes to say, “kelas, ignorance is bliss”. Here you go - all you ever need to know about how to read and write atwc:

https://github.com/kparc/bcc/blob/master/d/sidenotes.md#styl...

kelas··on Origins of J
> README

good idea, why not

for a more throw-me-in-the-water introduction, here are my notes on another famous public domain release from atw. some remarks are specific to the codebase, but essentially it is a general introduction to atwc:

https://github.com/kparc/bcc/blob/master/d/sidenotes.md

and here’s a less involved way to get lit:

https://github.com/aaalt/altc

kelas··on Origins of J
One possible way is to look at a header file i once gave to a 13yo girl. ever since she says she has no idea why people write tall c:

https://github.com/aaalt/altc

kelas··on Origins of J
porting from k&r to iso is super easy. fun, too.
kelas··on Origins of J
> not obfuscated

absolutely not. porting it to ISO C was a very fun and smooth ride, also added two adverbs atw forgot to add in 1989 (see over/scan) and a header file with some handy accesssors (atw usually does that, but he was lazy that day)

> to someone fluent in that programming style

what people often don’t realize is just how fast one can pick up atwc style, and how hard it is to ever go back :)

kelas··on Origins of J
> The code in C that suppose to be written like this is usually never written first like that

usually not. but we prefer to write it first this exact way, and there are good reasons for rhat.

> obfuscated c

it is not. this style is extremely regular, very readable and writable, and escapes a whole galaxy of typical C blunders. i can expand on that if you wish.

kelas··on Origins of J
> k is a fancy calculator

[put your favorite Java here] is also a fancy calculator by the virtue of Turing completeness. what’s your point?

kelas··on Origins of J
(author of the modern port here)

> Arthur Whitney is a mad genius

atw is atw :) our old man is awesome. a bit grumpy at times, but then who isn’t :)

kelas··on The rxv64 Operating System: MIT's xv6, in Rust, for SMP x86_64 machines
as of yet, it doesn’t shine quite as bright as current C/rv64 original.

but as they say, a long road begins with a single step.

kelas··on The rxv64 Operating System: MIT's xv6, in Rust, for SMP x86_64 machines
Thanks, that’s what I expected, but I don’t think I’m poorly received. It came out pretty positive and insightful. Hopefully not just for me.
kelas··on The rxv64 Operating System: MIT's xv6, in Rust, for SMP x86_64 machines
I think I see your point. Thing is, a C program can be built and executed without that cargo dependency pyramid sandwiched into a gigantic runtime polyp. The whole operating system is your environment, and yes - if ‘man ldconfig’ is not your friend, then maybe pkg-config is, or, worse to worst, link against project-local structure, where you can indeed build the bejesus out of your imagination and ship it. That’s ok. It’s linux, after all.

That’s what we do for embedded systems, anyway. I haven’t seen much success for rust in this department, although people are clearly trying to make it work. It just keeps coming out fat and ugly. A few more decades of hard push, call me a maybe.

Do you know what riscv version of xv6 rev3 compiles to in terms of object size?

I will not spoil it for you, but it compiles to total shreds.

kelas··on The rxv64 Operating System: MIT's xv6, in Rust, for SMP x86_64 machines
> The paper is entirely free. That's why I posted a link. Go read it. It's not very long, it's interesting, it's accessible, it's provocative and insightful and profound…

…and I already read it and you already have my reflections on this piece of work :)

> …SIMD and MIMD combined. C has no way of even beginning to express any of this.

Man, no hard feelings, but I suggest you start with K&R refresher and then work your way up to modern C. It is remarkably easy to learn, you’ll come around. What you deem impossible is very possible. Once you’re comfortable with basic C, I recommend cloning the repo of Lemire’s blog.

Just to see what’s available.

kelas··on The rxv64 Operating System: MIT's xv6, in Rust, for SMP x86_64 machines
> No, [C is not a high-level assembler], and it hasn't been for about 40 years. «C Is Not a Low-level Language Your computer is not a fast PDP-11.» some dude in ACM Queue

Please correct me if I’m wrong, but this ACM rant seems to amount to blaming C language for the most disastrous embarrassment in the history of Intel Corp, i.e. spectre/meltdown. Well, thank you very much, but that’s just deranged thinking, or someone was on INTL payroll in 2018.

but wow, thank you, what a gem. he then proceeds to elucidate how C is broken and again not low-level enough, because his 1337 skills require knowing the cache line size. well, this is absolutely true, captain Chisnall. but what is complete and utter nonsense is the conclusion that C is retarded by not letting the programmer manipulate the cache directly:

“The cache is, as its name implies, hidden from the programmer and so is not visible to C. Efficient use of the cache is one of the most important ways of making code run quickly on a modern processor, yet this is completely hidden by the abstract machine, and programmers must rely on knowing implementation details of the cache (for example, two values that are 64-byte-aligned may end up in the same cache line) to write efficient code.“

This deserves a WAT.

kelas··on The rxv64 Operating System: MIT's xv6, in Rust, for SMP x86_64 machines
> True, but when making an OS, assembly code is an incredibly small part of it.

A few comments up this thread i briefly mentioned r/xv6 entry.S, so here’s what i meant:

rv64:

https://github.com/mit-pdos/xv6-riscv/blob/riscv/kernel/entr...

amd64:

https://github.com/dancrossnyc/rxv64/blob/main/kernel/src/en...

> You basically need to run a few instructions to put the processor in the right mode, and you need ONE line of assembly code (often inline C) to allow usermode to call supervisor mode.

Right… Please see above. Also, in riscv land we have machine, supervisor and user modes, with hypervisor mode being in the works.

> When choosing an architecture for a learning OS, I think other factors would dominate, like availability of hardware (many people have a PC already, saving them $100-$200 on RISC-V hardware).

yet, MIT PDOS thinks Fabrice Bellard’s ubiquitous qemu is a better, cheaper and more forgiving starting point, although i personally prefer to spend a few bucks on something as absurdly cheap and cool as kendryte k210/k510 SoC and enjoy the real deal.

> Intel hate keeping tech is irrelevant [I don’t care]

Yes, it’s just you. Also, it runs Minix.

kelas··on The rxv64 Operating System: MIT's xv6, in Rust, for SMP x86_64 machines
> Different things entirely

yes, they are.

> System-specific packages have no concept of C building or linking.

every day i learn something new, but this time around I’m gonna go ahead a tell you that you are very mistaken.

> Things work because of some agreement about paths + pkgconfig + others.

True. By convention, we call it “convention”, or “standard” for short, e.g. POSIX or ISO C. Call us back once you have something like that in rustland.

> This is very far from the idea of a dependency manager like cargo which is very much aware of project-specific and language features.

All good and sound, and makes total sense for userland software. But what is being discussed here is an operating system and core userland. If you can imagine that to be your “project”, such as linux or OpenBSD, maybe my tongue-in-cheek comparison of a system-wide dependency manager suddenly looks less dissimilar to cargo.

needless to say, things like Linux and OpenBSD will stay written in C for a little while longer. In case of BSD specifically, you can go as crazy as to bump and rebuild your entire system from source in place, kernel and userland. BSD is one pretty old cargo cult in that sense, and pretty cool, i might add.

> language features

right… rust 2018 edition is not really rust as of 2023, or is it? This where those pesky standards come very handy.

kelas··on The rxv64 Operating System: MIT's xv6, in Rust, for SMP x86_64 machines
Sounds expensive, thanks. So:

Preface to the Digital Edition of Kernighan and Ritchie's The C Programming Language Oct 31, 2012

“… Remarkably, in spite of all of this change, C retains a central position. It is still the core language for operating system implementation and tool building. It remains unequaled for portability, efficiency, and ability to get close to the hardware when necessary. C has sometimes been called a high-level assembler, and this is not a bad characterization of how well it spans the range from intricate data structure and control flow to the lowest level of external devices.”

(sorry, I messed up the lyrics a bit, but also I didn’t, really)

Also, my computer is a fast Turing machine. And so is yours.

kelas··on The rxv64 Operating System: MIT's xv6, in Rust, for SMP x86_64 machines
thanks, this is useful, let me ponder. obviously i am also a subject of severe cognitive bias, granted.

but ok, if not uart driver - what other direct comparison in r/xv6 kernel spaces you would use to show where rust shows a real hard edge over C?

not a loaded question, I’m seriously asking for a valid pointer (no pun intended)

kelas··on The rxv64 Operating System: MIT's xv6, in Rust, for SMP x86_64 machines
+1

only xv6 gives traps, stack, uart, kalloc, preemptive scheduler, rudimentary fs, init(0) and minimal userland out of the box. students are not expected to implement any of that, it is hard - instead, is a book to read, a beautiful one. assignments are built on top of the core public codebase.

> Perhaps you suggest to use production-grade kernel like Linux, instead?

i imagine the expression on the student’s face once they run into their first:

/* not sure what this code does and why it is even here */

if it wasn’t for xv6, the best available choice would probably be OpenBSD codebase (not yet reimplemented in rust), but that’d be one hell of a graduate course.

xv6 is material for undergraduate 6.1810, a gentle introduction to operating systems.

← PreviousPage 2 of 3Next →