Hacker News new | past | comments | ask | show | jobs | submit login

FWIW, thanks a whole lot!

As an engineer in the forties it is somewhat encouraging to read that you felt the same way even if it was about different topics.

For me, these days it is about frontend generally, Gradle on backend and devops. So much to learn, so little documentation that makes sense for me. (I'm considered unusually useful in all projects I touch it seems but for me it is an uphill struggle each week.)

I always win in the end even if it means picking apart files, debugging huge stacks and a whole lot of reading docs and searching for docs, but why oh why can't even amazingly well funded projects make good documentation..?)




Just try, my pretties, just try to understand how exception handling actually works without staring at a lot of assembly.


Ah, doesn’t it just fly over to the nearest “catch”?

Btw, the worst misunderstandings I’ve seen were not lacking knowledge, they actively believed in some magic that isn’t there if you dig deeper. That’s why I still think that teaching at least basic assembler is necessary for professional programming. It can’t make you a low-level bare metal genius, but it clears many implicit misconceptions about how computers really work.


I recently picked up C after years of python, devops and javascript. I realized it's simply impossilbe for me to understand the tradeoffs made when other languages are designed or just understand my Unix-like operating system and other parts of it without knowing enough C. My next target is of course assembly and the compiler. And if anything I know, I want to stay away from any kind of sugar-syntax and unnecessary abstractions on top of basic computer and programming concepts.


Stack unrolling is a complicated process.

It's tempting to think of them as a kind of return value, but most languages do not represent them this way. (I believe it's a performance optimization.)

Flying to the nearest catch can also be complicated, as it's a block, that involves variable creation, and this possible stack changes. Again it's easier to model as a normal block break and then a jump, but that's not the usual implementation.


I always expect them to use (thread-) global state, not unlike good old errno just more structured. There's always at most one bubbling up so that's how I would do it.


But then you'll have a branch on every failable operation and slow down the happy path. This is not too different from passing the error as a value.

Instead, compilers use long jumps and manually edit the stack. I'm not sure it makes a lot of difference today, but branches were really problematic by the time the OOP languages were popularizing.


They're not bad these days if they're predictable. There's a code size cost, but there's also a cost to emitting all the cleanups and exception safety too.

For instance Swift doesn't have exceptions - it has try/catch but they simply return, though with a special ABI for error passing.


I believe that today a cold branch is just gets predicted as not taken and stays as such because it never jumps (in terms of a predictor’s statistics, not literally).


From the assembly one can learn what compilers do. But it cannot teach how modern CPU actually work. I.e. even with assembly reordering, branch prediction, register renames, cache interaction etc. are either hidden from code or exposed in a rather minimal way.


Right, in particular this is vital for Concurrency. In the 1990s my class about multi-tasking began by explaining that the computer can't really do more than one thing at a time. But in 2022 your computer almost certainly can do lots of things at the same time. And your puny human mind is likely not very well suited to properly understanding the consequences of that.

What's really going on is too much to incorporate into your day-to-day programming, and you'll want to live in the convenient fiction of Sequential Consistency almost all the time. But having some idea what's really going on behind that façade seems to me to be absolutely necessary if you care about performance characteristics.


Then there is no much difference between learning C and assembly. Both are languages for an abstract machine that has less and less relation to how things are done for real.


That is true.

But before I learned programming beyond BASIC, I took a course in solid state physics which went from semiconductors to transistors to nand gates to flip flops to adders.

Which made me very comfortable in understanding how CPUs worked. Not that I could design something with a billion transistors in it, but at the bottom it's still flip flops and adders.


> just fly over to the nearest “catch”?

No? (The stack unwinding is a whole process in and of itself.)


Well, I imagine that it would be possible by expressing its semantics using continuations. Implementing exception handling using call/cc seems like one of them favorite Scheme homeworks. And if you implement it that way, you should then know exactly what it does.


Although it's said that call/cc is a poor abstraction that's too powerful, and it'd be better to have its components instead.

https://okmij.org/ftp/continuations/against-callcc.html


Groovy? Gradle is a build tool for JVM.


Gradle.

Thankfully Groovy is not in the equation except for old Gradle files from before the Kotlin Gradle syntax existed.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: