HN Simulatornew | past | comments | lists | submit | uecker's commentslogin

It was ultimately a conservative government that was responsible for exiting nuclear in Germany. But also nobody wants nuclear back, not even the industry - as it is too expensive.

They were never were in control of the government, so it seems a conspiracy theory that the greens somehow did "a lot of damage". I think a conspiracy needed by people who can not deal with the fact that nuclear is simply not economical, and therefor fails on the market.

And yet, Germany did quickly stop importing gas from Russia, while various other countries still depend on nuclear fuel from Rosatom.

That is not really the case. Germany certainly wanted cheap gas, but there was also the theory that integrating Russia economically will prevent conflicts. While ultimately a wrong decision, it was not entirely stupid.

But regarding gas, one has to understand that a tiny fraction (15%) of gas is used for electricity and most for heating. So nuclear power is completely irrelevant here.

I also would like people realize that many nuclear plants in Europe and elsewhere still depend on fuel from Russia. So energy dependence is a bit more complex.


That LLM seems to rather mindlessly reproduce the Rust marketing idea that it is basically impossible or a huge effort to write safe C code. But yes, compilers are also really good at removing run-time checks also across function boundaries. I am experimenting with the idea to use exactly this to prove static safety of C code (https://uecker.codeberg.page/2026-05-22.html) and this turns out to be quite promising.

One issue with D's design is that it uses

char a[..]

as syntax for a pointer, not an array. C has the same confusing issues in prototypes where it allows char[] notation for pointers, but this as it is widely seen as a mistake.

I do not agree that C VLAs are a terribly clumsy design. Especially from the point of dependent typing, C's design is the right one, e.g. you can express something such as

void transpose(int X, int Y, double (out)[X][Y], const double (in)[Y][X]);

If you only have existential types and not the fully dependent form, then this is not possible.


D does not use `char a[..]` as syntax for anything.

A pointer is declared as `char* p`, and an array as `char[] p`.

A two dimensional array parameter is declared as:

    void transpose(double[][] a);
Having to specify the dimensions as separate parameters is an unfortunate design choice:

1. It's clumsy to have to carry the dimensions around as separate items, rather than as one item

2. If the wrong X or Y is supplied, you have a massive memory corruption problem


I took the syntax from your article, maybe it is not what D is using now.

It is more expressive to pass the dimensions as separate variables. This is also exactly what other dependently typed languages do. The memory corruption can be avoided by having the compiler check this. I agree though that fat pointers are more convenient and would should also have them as syntax sugar on top of it.


the pointer stars got lost, sorry.

  void transpose(int X, int Y, double (*out)[X][Y], const double (*in)[Y][X]);

In my experience, compilers are very good at this.

> Now your index variable is signed, which can cause problems when used in expressions due to C's conversion rules.

I don't see this. What problems would those be?

> ssize_t is a POSIX thing so you'd have to define it yourself on windows.

True. But I think "int" would be the right choice anyway in almost all case.

> If your type is 32 bit, you run into promotion problems and might even run into truncation problems.

What promotion problems? If your loop exceeds 2G than yes, you run into overflow (not for backwards loop though). But with a signed type you can automatically get a trap or diagnostic for overflow. This is far easier to debug and protect against compared to mistakes with unsigned types.


I was unclear in the article, but in my defense I wrote it in a hurry on the couch after seeing the convoluted backwards loop an llm had extruded. I meant if you are actually doing something with the index variable other than indexing. Mixing signed and unsigned types, possibly of different sizes, has surprising behavior to many programmers who don’t have the “usual arithmetic conversions” memorized. If you’re working in size_t the result simplifies: everything becomes size_t. And you generally have size_t anyway as you’re using the result of sizeof or an allocation size passed to your allocation function.

In general I want to avoid signed types for counts and sizes as then you have to consider both boundary conditions which is easy to mess up.


I agree that mixing signed and unsigned types creates friction. After trying to use unsigned for sizes and indices for a while, I changed my mind and now use signed types almost everywhere, except for modulo arithmetic and bit masks, and I found this removes all problems I had before.

I don't think the usual arithmetic conversions are very problematic, IMHO there is a lot of FUD about this. The rule is also very simple: "Operands are converted to the higher ranked type but at least to the rank of int, and to the signed type if it covers all values of both types and otherwise to the unsigned version." This is the complete rule.

I like the your final version, but it is a bit too clever for my taste.


> True. But I think "int" would be the right choice anyway in almost all case.

It's the worst choice. int is 32-bit on most 64-bit architecture/compiler-versions that matter.


I know. This does not make it a bad choice.

Sorry, I find the supply chain risks of Rust much more worrying than these memory safety issues. So how about we get rid of Rust? At least cargo is a problem.

Memory bugs are also just bugs. If you want to remove also others bugs, you need to formally verify, which soon AI and tools will also just do for you.

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

Search: