jstimpfle

Joined 11 years ago

Karma
4,224
Submissions
3,568
Member since
May 21
http://jstimpfle.de
View on Hacker News

Recent submissions

Comment · 20 hours ago
Probably reading something into this that I didn't mean?
Comment · 1 day ago
About progressive taxes. That would make the super rich not super rich. But it would not fix state finances. (Also of course it's not realistic to think that the super rich will just give 100% of their money for nothing in exchange).

If the state needs money, it needs to take it from where it is, which is still with the masses. In Germany, at around maybe 90k EUR income is a particularly bad place to be. You are nominally considered to be a good earner. But at that point you already give around 70% on the next EUR you earn for various taxes and social security. If you are financially responsible not only for yourself but for other people (which is not reflected in lower taxes unless you're legally married), you can still get along fine, but it might not feel like you are a good earner. I was in a similar situation at one point in my life, it had taken me hard work to earn that money, and I have to say I was a little pissed about the tax situation.

I think I understand why progressive tax systems exist. Given our societies' structures, they probably _have_ to exist. But also I wonder if long-term they _contribute_ to income and wealth inequality. It reduces incentives for those who earn less to earn more (which of course for many people is not easily possible, but for some it would be, by working more, working harder, looking for a different job, etc.). It also allows employers to spend less on their workforce, meaning you could understand it as a kind of subsidiary for employers. Of course, lower salaries might be the only way for employers to even offer a product at prices the market wants to pay. But again it also reenforces inequalities in the income structure.

Comment · 3 days ago
That's just a matter of wrapping the allocator if you feel fhat is better approach. Question is, should there always be an allocator around with arr or do you want to split a build phase from an immutable use phase.
Comment · 20 days ago
I find both of these names too long and the colons are noisy. The fact that I can refer to them using different qualifications makes me uneasy. For both we could find better names, e.g. MemoryOrder is already an established term.

I've realized that naming is an art that is difficult to master but makes a huge difference when gotten right. It consists of not just combining names into compounds but also finding new shorter names that are ergonomic and distinguishable. For example, I've replaced the compound "NodeIntersectTest" in my current project with simply "Probe", which is much easier to read and write, easy to distinguish from other terms after learning its meaning once (it is a central concept to my app), and also perfect for log messages and stats where brevity matters a lot.

A two letter prefix for all identifiers in a project or company codebase is a good idea, but I try to avoid hierarchies and finer granularity, and generally to be overspecific, in order to keep things easier to change later.

Comment · 20 days ago
True that integer promotion rules are defined in terms of the machine dependent unsized "real" integer types. That is indeed annoying. I guess I've found ways to cope. Good thing is, those promotions never cast down, they only widen types.

The point of namespaces is exactly to allow less qualified names, to allow spending less energy when creating new names, by having the compiler always add a qualification implicitly. However, that doesn't solve the problem with name collisions when reading or grepping the source code -- it actually makes it much worse. And avoiding those name collisions, i.e. what's in the source literally, what the programmer reads, and what less-than-perfect tools see, is at least as important as avoiding "semantic" name collisions and being able to compile the code.

Namespaces not only encourage many more literal collisions -- now a single name can be available in various shortenings, and even under different aliases, which also makes it hard to tell that two symbols refer to the same thing!

I've found that the only way to get names right is to find a good scheme, to find meaningful good prefixes, suffixes, and abbreviations, and to come up with a system to create new names more mechanically but still keep them as short and readable as possible.

Comment · 20 days ago
True. In C, it's hard to know what's defined where and what dependencies one is even using unknowingly. The only help is to build on multiple platforms from early on, this will reduce the pain of porting to new platforms later.
Comment · 20 days ago
Integer widths are a problem, but hardly the biggest headache (unless it's a decade old preexisting project that was never designed with portability in mind). Fixed width integer types like int32_t have existed for decades. Even Rust has usize which is machine dependent, and pointers as well have to be machine dependent of course.

Much bigger problem is understanding the scope of dependencies. Dependencies can go bad and you need to update. A dependency might not be available on some new platform so you might have to replace with something else on that platform. To make the software portable, good modularity is required. This is to a large extent an aspect of software architecture. Even Rust can't magically make this happen, if you depend on 300 crates that's probably not a great place to be in either if you want to be portable and maintainable.

There is probably a point that C's flat namespace is a major contributor to badly designed software, because people aren't aware of the dependencies they're mixing all the time. Also C encourages transitive includes, leaking implementation details to the user instead of just to the compiler. (But btw. I find C++ and Rust namespace to be unergonomic syntax-wise, and what's needed is not actually namespaces but control over visibility).

Comment · 20 days ago
It's _very_ easy to write C that is impossible to port to other platforms or other compilers. The reason is that more than for most other ecosystems, there are many different implementations with their own implementations and quirks.

It's also easy to write C that won't build on the system it was originally developed on, a few years down the line. But that is true for almost every other language ecosystem. I would say, C makes it _possible_ to write code in such a way that it works on many different platforms and compilers, and/or can continue to work in decades to come with relatively little maintenance.

The latter isn't true for most other ecosystems, because to get anything done in them, you need to rely more on that language and its ecosystem -- specific language features, specific libraries. C isn't a glue code language. It's very good at letting you create your own thing.

To do it well though, requires a lot of care and expertise.

Comment · 25 days ago
It couples things and complicates things. Which creates friction against when refactoring a software architecture, making it harder to scale it up.

Fully agree, for locks or other simple begin/end pairs it doesn't create the same kind of architectural damage. But I don't use it even there, because RAII fundamentally doesn't play well with manual cleanup code. It's kind of an all-in game, if you use some RAII there are strong forces (whenever you need to get the "nesting" right) to convert all remaining manual begin/end type code to types that define that functionality out-of-line in the destructor/destructor, leading to fragmentation.

Comment · 25 days ago
No need to invent when you already know how it works.

I could re-type all the essential stuff from std::string that I've ever used myself within 10 minutes, no problem, without looking up external sources, including copy & move semantics and whatnot. But I'm deliberately not doing it. Because I don't like this "invention".

Comment · 25 days ago
The projects and people I follow do this all the time. Just like putting a size field near each regular non sentinel terminated array is useful. But if not doing it (maybe linux kernel in many cases), no big deal either, don't sweat the small stuff. String slices are small and rarely perf critical.
Comment · 25 days ago
Placing data in .rodata (read only memory) is an actual useful application of const keyword. Not specific to embedded. Arguably there shouldn't have been multiple slightly different meanings of the keyword like that.

I don't know why you are now jumping to setjmp/longjmp, trying to make a point that somehow C is the worst programming languages ever, when all I am trying to argue is for sane programming practices, hinting that more complex features (line especially found in newer languages) are not solutions but part of the complexity problem.

Comment · 26 days ago
Yeah... There are libraries like Google Highway but that seems to me like a bulky software abstraction layer even if it is a so-called "zero cost" abstraction. Maybe appropriate in some cases. In my case, I've implemented a couple of lines for AVX2 and AVX512, maybe around 100 lines for the most perf sensitive sections currently, not a big deal. The actual work is in the understanding of the problem and of the phyiscal hardware, and in the software architecture and data layout to even enable vectorized stream processing in the first place. I'm not concerned writing a couple of perf sensitive lines against 2-3 most important concrete vector ISAs. I also fancy adding a GPU backend later (requires D3D12/SM6.0 API level), Highway couldn't help with that.
Comment · 26 days ago
> Do you expect some other behavior in such case?

No, just saying this stuff is implicit and thus hard to read. More so the allocation on indexing assignment. and keeping things which shouldn't be mutated const wasn't a problem at all.

> and keeping things which shouldn't be mutated const wasn't a problem at all.

As soon as datastructures become more complicated and more interconnected, it's not clear anymore what const should even mean (issues are similar as with deep vs shallow copies, how do you even draw the lines, where are the objects?).

And the major philosophical flaw in the const vs. non-const distinction is that to make a strict separation you have to move everything mutable into constructor calls (for the most part, not getting more into the weeds of C++). Which is very awkward, it's a real tradeoff you need to be aware of. I realized only after playing these games for a long time what a waste of time it is and how much complexity it creates.

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton