Hacker Timesnew | past | comments | ask | show | jobs | submit | zahlman's commentslogin

> The source I linked to above cites Mathematical Cranks by Underwood Dudley, but I couldn’t find it in the book.

I don't know why someone would make an AI slop fake of old mathematical crankery, but I think that has to be considered as a possibility. Especially given that the formula is being attributed to Dudley, who was actually cataloguing the nonsense of others.

(Also, a conventional Internet search tells me that Dudley was born in 1937, not 1912; and that rather than dying in 2005, he is still alive.)

(Perhaps Cook noticed these things and is too polite to point them out?)


It's hard to be totally sure, but I also don't think that's a picture of Dudley.

> There will always be cases (like audio processing, car brakes, pace makers) where hard real-time constraints prohibit GC languages (as well as l1 cache, instruction reordering and other optimizations). Also, consider that Python's performance frequently originates in it's bindings to libraries written in C, C++, Fortran, Rust.

Sure. And every Python programmer who has any interest in those use cases learns about the issues quickly. Or more to the point: a big chunk of them are things you'd only do if you were employed to do them, and employers are setting the language requirements already. And Python programmers in particular are well aware of compiled-language bindings; that's the reason they're trying to use the packages that make package installation non-trivial.

Huge swaths of use cases don't require performance.

> Python, Java or TypeScript are good educational tools, but you'd be doing yourself a disservice if you'd confine yourself to them without understanding computers.

This is an extremely strange thing to say when replying to someone who just described having extensive experience with C++ and multiple flavours of assembly.

> I recently ran a few Java benchmarks and found that an array holding a bunch of objects incurred approx 3x the number of bytes compared to the expected number based on underlying class data structure.

It was also strange to say that if you also had this experience yourself. A solid "understanding of computers" would have given you a better mental model of what Java needs to allocate. Results like this are because "the expected number" was not well thought out.

> if you're building software that's meant to scale.

... And yet everyone just keeps pumping out Electron apps. Curious, that.


> Hey Python users: you know that in the end everything ends up as machine code, don't you?

I don't understand where you're trying to go with this call-out, especially if you're also describing yourself as a Python user.

But, like, no, not really; ordinarily, Python is bytecode-compiled and then the bytecodes are interpreted. There's machine code doing the interpretation, but that interpretation is not transformation.


Many years ago I remember going through the Boost library and seeing C-style casts that seemed entirely gratuitous. I tried replacing them with what I was pretty sure were the equivalent C++ reinterpret_casts, and the result didn't compile. I never did figure it out.

C style cast can be either a static_cast or reinterpret_cast, but it can also be a const_cast or a static+const or reinterpret+const. Finally, it will perform a static_cast that bypasses private inheritance (because the alternative would be to fall back to a reinterpret_cast, which is wrong if the static_cast needs to apply an offset to the pointer)

> a static_cast that bypasses private inheritance (because the alternative would be to fall back to a reinterpret_cast, which is wrong if the static_cast needs to apply an offset to the pointer)

That may well have been it, then. I would think that if it could have been expressed naturally, it would have been.

(I don't think I ever used private inheritance in my own C++ code. I'm not a huge fan of inheritance at all, so.)


To add on top of sibling comment, C style casts are too lose, and the main reason for the new C++ style casts is improved type safety.

So instead of anything goes, there is some additional type checking depending on the type of cast being made.


> a "simple" and "beautiful" function that was mangled into incomprehensibility over the years, and where if a more expressive type signature had been written from the start, it would have restricted the damage caused over time.

...Can you give a concrete example? I've been programming literally since the 80s and that doesn't ring true at all for me.


> ...Can you give a concrete example? I've been programming literally since the 80s and that doesn't ring true at all for me.

Even this week I stumbled upon legacy code that started off with a clean function, void DoSomething(Foo). Then a few years passed and someone started using Foo to handle two scenarios, let's call them Left and Right. They could have simply introduce two new types, FooLeft and FooRight. But no. Instead they kept Foo after adding a few extra optional fields, and extended DoSomething(Foo) as

    DoSomething(Foo foo, bool isLeft, bool isRight)
This took place during the mid 2010s.

Where have you been during all this time?


Have you been in static types the whole time? It's a really, really common failure state in dynamic programming languages, the Everything Function, that started out as something simple, but then someone added a flag to make it also do this other thing, and then you need a flag to only do that other thing sometimes, and someone needed to operate on multiple things so they made a string parameter also optionally an array, and later someone allowed it to also be an object with this one method, or maybe another method if it's present because some other team implemented that before the first one and can't switch now, and before you know it it's a free-for-all of people adding flags and options and type analysis and if statements and you have a complete mess. Especially if this function is shared by many disparate teams, each of whom isn't "allowed" to break the others, though a single team can fail this way plenty fine.

You can still do this in static languages, but they do push back a bit more because you don't get the flexibility that dynamic languages offer when it comes to accepting a huge variety of different input types.

I've torn a few of these apart over the years. Never fun. Haven't tried with AI but suspect that would only be a quantitative change rather than a qualitative change. The fundamental problem with fixing these is lack of information about the exponential complexity of possible call mechanisms and the AI will have the exact same information problems I will, just faster.

Edit: One of them that I tore apart ended up being two entirely separate functions slammed together into one by historical contingency. I don't just mean that I broke the functionality down into multiple functions, that's a basic tool of how you tear these down and is nothing of note. I mean that one of the "everything functions" I tore down had two distinct calling patterns that were distinct functions that not only shouldn't have been festooned with so many options, but never should have been one function at all because they weren't even conceptually the same thing or even particularly related.

Think of it as two stages of a straight-line process, that were just jammed together because of the fact they got called at similar times, and the original writers weren't clear on the unrelated nature of the tasks and nobody was able to see it through all the obfuscation until I sat down, very deliberately, and I realized this as I was tearing it apart. I don't remember the details, I tend to remember things very conceptually and thus I have a hard time remembering the details of functions with no conceptual purity, but you can get close by thinking of the function as validating incoming parameters, and then applying the parameters to a database. And people were so confused that despite the fact this function, when tickled correctly, could do it all in one shot, sometimes, kinda, with some caveats, there were places where this function was called first to validate (with flags to shut off the application), and then to apply (with flags to shut off the validation). And to be clear, I mean, I did not realize it either even from my contact with the function over the years. It was only when I sat down with it for hours and systematically tore it down that I figured that out.


I can't, as my employer owns the code, not me, but there are several examples in one of the Ruby codebases I unfortunately maintain where I can see this degeneration happen via the git history. A small 8 line method with just two parameters slowly grows in complexity over time, until one day one of the original parameters supports two different shapes, and later on it's not that easy to understand which shape it should have in the specific conditional branch you're trying to fix, and the last person to touch that code left the company 4 years ago.

The fault, of course, ultimately lies with the people who wrote and approved this nonsense, but types, or at least type hints, help to avoid this issue.


You’re really citing a mess in a Ruby code base caused by lack of typing as evidence for why void * is problematic in C/C++?

These are so wildly different cases that the comparison isn’t meaningful. This is like saying you should wear a helmet while playing tennis because sometimes helmets save bicyclists lives.


> You’re really citing a mess in a Ruby code base caused by lack of typing as evidence for why void * is problematic in C/C++?

If you read GP's post you'll understand it exemplifies exactly the issue that the likes of (void *) present in C.

I mean, read the message, particularly this:

> later on it's not that easy to understand which shape it should have in the specific conditional branch you're trying to fix

That is exactly the purpose of void *. By design. It's a pointer to an unspecified type. The unspecified type is exactly why this thing is used.


Can you point to it? That doesn't sound like "the language forced all this extra baggage on it due to 'safety'" so much as the developers kept adding functions to the function without rethinking if and how they should.

My point was not about the safety of the code, it was about the expressiveness, which is also what the comment I replied to was about. If the parameter has an explicit type (instead of no type, as is normal in Ruby, or `void*`, which is the C equivalent), it forces the developer to consider the design of the function, instead taking the path of least resistance because they're inexperienced/incompetent/a large language model/burnt-out to the point where even the thought of opening the file makes them feel the not-anxiety of burnout/<insert reason here>.

> instead of no type, as is normal in Ruby, or `void`, which is the C equivalent*

“void *” is not the equivalent of “no type” from Ruby. “void *” says “I operate on raw memory”. It says exactly the same thing as “byte *”.

For sure you should generally not write a function that accepts a “void *” and then internally casts it to some concrete pointer type and operates on that type, but the problem there is the internal behavior, not the choice of byte vs void pointer.


Forcing developers to consider and more is harmful though. You're arguing to put all of the forethought upfront, when you have the least context and least understanding of what can go wrong, and carrying that complexity forward rather than starting simple and refactoring over time.

> Many website will request my personal physical address for trivial matters like billing or delivery. That can not under any mean be considered public data.

I just don't buy things online, and avoid anyone having my physical address that way.

Sadly, the ubiquity of terrible 2FA means at least some companies have my phone number, though.


> I don't create new accounts, I never cross-login with my email address

... you don't create burner email addresses specifically to cross-login with them to one service?


What if I only have baking soda around normally, and not baking powder?

What if I have bottled lemon juice and can't zest an actual lemon?

Also I hoped to see heavy cream listed as an ingredient.


> There's so much click-baity LLM language

You're absolutely right. It's not just Claude that gives you output like this — it's every model.

(Ahem, sorry.)


> About the only grace I give these manufacturers is the fact that google and apple both make it an annoying pain to maintain applications in their app store. A manufacturer can't simply drop "oven app" once and expect it to be available on the store forever.

If the app doesn't use the Internet then the natural way to provision it is to have it pre-loaded on the device anyway. Why should the goal of "avoid needing to hit the manufacturer's servers" involve hitting Google's servers?


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

Search: