People complain about the imbalance between economy supply and economy demand leading to inflation and debt concerns.
The complaint isn’t that the economy is “circular”, how else could it work with 3 or more people engaged in commerce? Neither of those things get fixed on different ways to manage the money supply either, it’s not as if they didn’t have national debts or inflation while on the gold standard.
It’s just a different format. Providing liquidity in the hope that more is generated from the economy. Except it’s doing more harm than good other than in true crisis. Other times it’s just creating a bubble, in national debt and in AI.
It doesn’t help Google to create an AI-powered business which turns $1B in profit annually if it results in them losing a search/ads business which turns $5B in profit annually.
The CapEx spend for AI not only makes AI itself more expensive (and thus less profitable), it’s now driving everything else in technology to be more expensive (and thus less profitable).
AI is a profitability tax on the entire tech sector and it remains unclear if the profit AI will deliver is going to be worth that.
I would say they should slow down on build-out to balance supplier/labor availability with available cash flows, but I suspect all the Big Tech companies are worried about falling behind the other and being put in the position to need to rent out compute.
It’s more or less certain that Anthropic is already profitable if you discount the losses due to becoming too valuable.
What you are saying here
> The CapEx spend for AI not only makes AI itself more expensive (and thus less profitable),
There’s nothing inherently unique about this. It’s just supply and demand - the only problem is that the ecosystem of raw materials can’t keep up with the demand. It will catch up soon and the prices will stabilise.
Your only problem seems to be this aspect only: that RAM production hasn’t increased according to demand.
No I don’t agree they should slow down. I think RAM and other things should rather speed up to react appropriately to the demand.
It’s like saying the iPhone is not profitable because too many people want it and its price is going up.
The introduction of the mouse led to developers paying less attention to keyboard shortcuts and function keys, but I don’t see anyone seriously saying computers should not have mice.
Or for that matter, that adding support for game controllers (something that has actually happened with Linux desktops) would led to curtailed development of non-controller parts.
> The introduction of the mouse led to developers paying less attention to keyboard shortcuts and function keys, but I don’t see anyone seriously saying computers should not have mice.
Well, a lot of devs did move back to the terminal ;)
I encourage it! I think having to deal with switching between mouse and keyboard actually accentuates why the terminal is nice as an interface so often. If it does nothing more than make someone building a terminal app think just a bit harder about where to be intentional about user workflows so that a mouse is not even required then it may even have helped keyboard-only uses.
It's sort of weird in a world that has moved to an DevOps-style ethos for most development.
But yes, before that it would be not at all unusual to have “test engineers” or other technical staff whose entire responsibility laid with setting up test environments and running QA of products. These people did not do product dev, though they may have been involved in writing supporting test platform libraries or even maintaining test infrastructure (like IBM Jazz).
Even today in the U.S. companies that haven’t fully jumped onto newer development practices probably still have QA and/or test departments.
>It's sort of weird in a world that has moved to an DevOps-style ethos for most development.
The world at large makes all sorts of trends, and that by itself doesn't make them smart. As a developer, you are likely to have blind spots when it comes to quality and reliability as a result of having written the code. Even a team of developers cross-testing each other's code will not have the same ability to find flaws (before they embarrass you in front of the customer/client/user) as a dedicated tester whose job it is solely to find new (and old) ways to break things (and document them.)
DevOps is a completely different thing (though they work together with testers.)
It is only weird to have dedicated QA on your team if you don't give a fuck about releasing shit with bugs in it for the user to bump into.
> The world at large makes all sorts of trends, and that by itself doesn't make them smart.
I never said it was smart. Or dumb, for that matter. Just that many product teams have been made to merge testing responsibilities as an internal responsibility, in line with having end-to-end ownership of the product from development to its operational deployment. And usually without any dedicated test engineer member of that team to do this.
> It is only weird to have dedicated QA on your team if you don't give a fuck about releasing shit with bugs in it for the user to bump into.
Well, has the behavior of software companies led you to believe they care strongly about this? I always got the impression they cared more about either maximizing feature velocity given a certain team size, or minimizing labor cost for a given feature velocity.
Isn't this still a thing? "Software Engineer in Test" being the newer term?
I just checked LinkedIn and they have quite a few job listings in this vein. Which makes sense: in the "AI and YOLO" development lifecycle, automated testing is more important than ever.
> That's no surprise, "unreachable()" is basically an instruction to the compiler to stop generating code from that point on, and the compiler obeyed.
It's not a command to compiler to stop generating code.
It's a permission slip that allows the compiler to assume that code that follows is dead code, eligible to be optimized out, including eliminating potentially dead stores and loads.
Which is to say, it's precisely what any other UB is, which is why deliberate use of UB is very bad idea.
No one is surprised that defensive code isn't issued to guard against p being NULL, unaligned, or pointing to a uint16_t. You told the compiler that p is actually pointing to a double, and it generates code accordingly.
It's the same thing here: You told the compiler very explicitly that anything following this point is unreachable, and it generated code accordingly.
I'm not defending writing code with UB. I would have preferred the compiler issuing a warning saying "you say this is unreachable, I don't believe that it is", when it's this obvious. Maybe issue a trap instruction. But there's nothing wrong it, per se. When you choose to override the compiler's judgment and insist that this point in code is unreachable, then the compiler takes your word for it.
Of course I would also prefer a warning, or at least a guarding trap instruction. And maybe compilers should try harder to be friendly in this way.
But they can't be perfect, because the program specified something syntactically valid, but semantically invalid. The module/compiler pass that could theoretically detect it may simply not be issued the necessary information. E.g. a solver may be given the input that a value is in a given range, and from that simplify an operation. If the input is wrong, so is the output.
Reminds me of:
On two occasions I have been asked, 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question.
In the example from the article, though, there could be a pass that simply eliminated dead code. That pass is not a parser of the raw code, so how is it to know that actually, the "dead code" isn't?
And a standard that would require dead code elimination to replace not with empty, but with a trap instruction, could go very wrong. You don't want `if (false) { … }` to become `if (false) { trap(); }`. You want it just removed, if a previous pass deemed it dead. Or do you want `int main() { for(;;) {cli_loop();} }` to force adding a trap in the unreachable code after the loop? That's a lot of generated trap instructions.
So in general this means solving the halting problem. Yes, specifically in the post's example, "surely a sufficiently smart compiler could detect something this obvious". Maybe so, but how often is the bug actually this obvious?
The solution is to avoid UB. std::unreachable() is just an easy-to-invoke way of hitting UB, mentioned for the sake of the discussion. They did later take your advice “Let’s say we change std::unreachable() to int* ptr = nullptr; *ptr = 99; in the previous example.”. They still got improper codegen out of the compiler.
Though, it would be better if programmers read deliberate instances of UB as if they literally said "std::unreachable()" at that point in the code, as that would better convey how the optimizer passes will see things after dozens of frontend and middle-end passes have run before it.
> it would be better if programmers read deliberate instances of UB as if they literally said "std::unreachable()"
Except that isn't true.
There are basically two kinds of undefined behavior.
The first is undefinable behavior, the kind that easily goes disastrously wrong, like writing to random memory locations.
The second is incidentally undefined behavior, something where there just isn't enough implementation consensus for the standard to settle on it, like realloc(p, 0).
There's no standard terminology I'm aware of to distinguish the two. But the distinction exists.
And where programmers read deliberate instances of UB, it's usually the latter, e.g., writing directly to an address memory mapped to device I/O in that particular environment.
> There's no standard terminology I'm aware of to distinguish the two.
There is: implementation-defined behavior. Your example of writing to an MMIO address is such an example, as the standard says casting an int to a pointer is implementation-defined. (However, the C standard has plenty of cases of undefined behavior that probably should have been implementation-defined.)
You seem to be conflating the act of writing to an arbitrary address with the act of assigning that arbitrary address to a pointer to begin with. They are distinct actions.
> There's no standard terminology I'm aware of to distinguish the two. But the distinction exists.
This distinction exists, but not to the compiler. And the compiler is the thing building your binary. You can complain if you like about how UB that could potentially instead have been implementation-defined is UB instead.
But until then, the compiler will mangle your code either way, whether you feel it is fair or not.
> We can also lay some blame at Agile's feet. I've seen UX and UI designers genuinely struggle to fit their work into the sprint treadmill. 2 weeks' notice is not enough time to do any sort of serious usability design study.
Windows 95 significantly overhauled the desktop GUI metaphor, in a way that is still the skeletal structure of desktops today.
> We recognized that we needed much more opportunity to create a design, try it out with users (perhaps comparing it to other designs), make changes, and gather more user feedback. Our desire to abandon the waterfall model and opt for iterative design fortunately followed similar efforts in other areas of the company, so we had concrete examples of its benefits and feasibility.
You're right that you can't go start to finish on a design in a single 2-week sprint. But that's why you have a repeating series of sprints, you're not supposed to go from start to finish in a single sprint.
The Windows 95 team always had a shippable OS to demo internally to devs, QA, beta testers and users invited by the UX designers for usability testing. Just because you demo something to the product owner does not require that you then release the result immediately to end users. Decouple development from deployment and from release and you'll find agile methods can work just fine.
Perhaps instead of Agile I should have said "What Agile became in the 21st century." I know how Scrum is supposed to work. I just haven't seen anyone actually do it that way since about 2013.
I don't think you can credit Windows 95 to agile when the agile manifesto was first published in 2001 and the whole sprint nonsense didn't start until sometime later. Iterative development goes back to at least the 80s and doesn't require "scrum masters", "sprints", or "t-shirt sizes".
> I don't think you can credit Windows 95 to agile when the agile manifesto was first published in 2001 and the whole sprint nonsense didn't start until sometime later.
Agile manifesto coined a term for things that already existed. It didn’t create it from scratch, nor did it claim to. But W95 did employ methods we would call agile methods today.
I do think that they were right, though, to point out that the practices already existed and that they aren’t inherently at odds with, and ideally support, good UI design. And the linked article makes a good case that Win95’s UI design was done in an agile way.
That’s not the part I intended to criticize; it was the modern tendency to discard iterative design and instead just treat sprints a series of immutable milestones with fixed deadlines, except the scope is fixed in a just-in-time manner. But it’s on me for not stating that more clearly.
We already have enough memory-unsafety bugs going around without making free() more difficult to use correctly as well.
reply