Up from 35 years. Average age is currently 22, though.
Air Force and Space force went to 42 years back in 2023. The Navy went to 42 years in early 2026.
Maximum age for the Marines remains 28 years.
With high youth unemployment [1], it ought to be easier to recruit.
The land war is getting closer. The Army's 82nd Airborne has been sent towards Iran. Possibly to take Kharg Island, one of the very few objectives for which an airdrop might possibly make sense.[1] Possibly. 2nd Marine Expeditionary Force is already on the way.
800V to each rackmount unit, with hot plugging of rack units? That's scary.
The usual setup at this voltage is that you throw a hulking big switch to cut the power, and that mechanically unlocks the cabinet. But that's not what these people have in mind.
They want hot-plugging of individual rackmount units.
GE has a paper about the power conversion design, but it doesn't mention the unit to rack electrical and mechanical interface. Liteon is working on that, but the animation is rather vague.[2] They hint at hot plugging but hand-wave how the disconnects work.
Delta offers a few more hints.[3] There's a complex hot-plugging control unit to avoid inrush currents on plug-in and arcing on disconnect. This requires active management of the switching silicon carbide MOSFETs.
There ought to be a mechanical disconnect behind this, so that when someone pulls out a rackmount unit, a shutter drops behind it to protect people from 800V. All these papers are kind of hand-wavey about how the electrical safety works.
Plus, all this is liquid-cooled, and that has to hot-plug, too.
> When it is detected that the PDB starts to detach from the interface, the hot-swap controller quickly turns off the MOSFET to block the discharge path from Cin to the system. After the main power path is completely disconnected, the interface is physically detached, and no current flows at this time
> For insertion, long pins (typically for ground and control signals) make contact first to establish a
stable reference and enable pre-insertion checks, while short pins (for power or sensitive signals)
connect later once conditions are safe; during removal, the sequence is reversed, with short pins
disconnecting first to minimize interference.
The relay they're using is quite likely to fail. It's a no-brand imitation of a relay where the real one is only rated for 10^5 cycles driving an inductive load.[1] Also, they needed a DPDT relay, which they are emulating using two SPDT relays operated together. If the software ever operates only one of them, the door will remain locked regardless of what the entryphone box does. Also, no fuse or snubbing. There's a whole industry of really crappy control relays from China, especially on the solid state relay side.
A useful device to know about is the Relay In A Box line.[2] This is exactly what it says - a relay in a box, for when you need to switch power with a low-voltage control signal. UL and CE approvals, fits standard electrical conduit fittings, and will pass code inspection. Rated for 10 million cycles. Boring, but useful.
Note the use case - someone wants to have the ability to replace a base-level crate such as serde.
When something near the bottom needs work, should there be a process for fixing it, which is a people problem? Or should there be a mechanism for bypassing it, which is a technical solution to a people problem? This is one of the curses of open source.
The first approach means that there will be confrontations which must be resolved. The second means a proliferation of very similar packages.
This is part of the life cycle of an open source language. Early on, you don't have enough packages to get anything done, and are grateful that someone took the time to code something.
Then it becomes clear that the early packages lacked something, and additional packages appear. Over time, you're drowning in cruft. In a previous posting, I mentioned ten years of getting a single standard ISO 8601 date parser adopted, instead of six packages with different bugs.
Someone else went through the same exercise with Javascript.
Go tends to take the first approach, while Python takes the second. One of Go's strengths is that most of the core packages are maintained and used internally by Google. So you know they've been well-exercised.
Between Github and AI, it's all too easy to create minor variants of packages. Plus we now have package supply chain attacks. Curation has thus become more important. At this point in history, it's probably good to push towards the first approach.
It's a social problem that's created by a technical problem.
In many languages, if you want to integrate package A with package B, you can make and share a package AB, which people can reuse. That scales, and facilitates reuse, and avoids either package having to support everything.
In Rust, if the integration involves traits, integration between package A and package B must happen either in A or in B. That creates a scaling problem, and a social problem.
Other than duck-typed languages (and I count Go as basically that), which languages actually provide this feature?
AFAIK, it’s not really very common to be able to extend foreign types with new interfaces, especially not if you own neither.
C++ can technically do it using partial specialization, but it’s not exactly nice, and results in UB via ODR violation when it goes wrong (say you have two implementations of a `std::hash` specialization, etc.). And it only works for interfaces that are specifically designed to be specialized this way - not for vanilla dynamic dispatch, say.
> Other than duck-typed languages (and I count Go as basically that), which languages actually provide this feature?
There are only like 3 significant languages with trait-based generics, and both the other ones have some way of providing orphan instances (Haskell by requiring a flag, Scala by not having a coherence requirement at all and relying on you getting it right, which turns out to work out pretty well in practice).
More generally it's an extremely common problem to have in a mature language; if you don't have a proper fix for it then you tend to end up with awful hacks instead. Consider e.g. https://www.joda.org/joda-time-hibernate/ and https://github.com/FasterXML/jackson-datatype-joda , and note how they have to be essentially first party modules, and they have to use reflection-based runtime registries with all the associated problems. And I think that these issues significantly increased the pressure to import joda-time into the JVM system library, which ultimately came with significant downsides and costs, and in a "systems" language that aims to have a lean runtime this would be even worse.
> Scala is interesting. How do they resolve conflicts?
If there are multiple possible instances you get a compilation error and have to specify one explicitly (which is always an option). So you do have the problem of upgrading a dependency and getting a compilation error for something that was previously fine, but it's not a big deal in practice - what I generally do is go back to the previous version and explicitly pass the instance that I was using, which is just an IDE key-combo, and then the upgrade will succeed. (After all, it's always possible to get a conflict because a library you use added a new method and the name conflicted with another library you were using - the way I see it this is essentially the same thing, just with the name being anonymous and the type being the part that matters)
You also theoretically have the much bigger problem of using two different hashing/sorting/etc. implementations with the same datastructure, which would be disastrous (although not an immediate memory corruption issue the way it could be in Rust). But in practice it's just not something I see happening, it would take a very contrived set of circumstances to encounter it.
C# does not support adding interfaces to foreign types. It does support extension classes to add methods and properties to a type, but nothing that adds fields or changes the list of interfaces implemented by a type. Rust supports this as well, because you can use traits this way.
Dependency injection is a popular solution for this problem, and you can do that as well in Rust. It requires (again) that the API is designed for dependency injection, and instead of interfaces and is-a relationships, you now have "factories" producing the implementation.
This is interesting but I wonder if you would accept that this also has the downside of moving at the speed of humans.
In a situation where you're building, I find the orphan rule frustrating because you can be stuck in a situation where you are unable to help yourself without forking half of the crates in the ecosystem.
Looking for improvements upstream, even with the absolute best solutions for option 1, has the fundamental downside that you can't unstick yourself.
This is also where I find it surprising that this article doesn't mention Scala at all. There are MANY UX/DX challenges with the implicit and witness system in Scala, so I would never guess suggest it directly, but never have I felt more enabled to solve my own problems in a language (and yes the absolute most complex, Haskell-in-Scala libraries can absolutely an impediment to this).
With AI this pace difference is even more noticeable.
I do think that the way that Scala approaches this by using imports historically was quite interesting. Using a use statement to bring a trait definition into scope isn't discussed in any of these proposals I think?
The problem is existentials, or rather the existence of existentials without the ability to explicitly override them. Even in Haskell, overriding typeclass instances requires turning off orphan checks, which is a rather large hammer.
So once you've identified this, now you might consider the universe of possible solutions to the problem. One of those solutions might be removing existentials from your language; think about how Scala would work if implicits were removed (I haven't used Scala 3, maybe this happened?). Another solution might be to decouple the whole concept of "existential implementations of typed extension points" from libraries (or crates, or however you compile and distribute code), and require bringing instances into scope via imports or similar.
Two things are true for sure, though: libraries already depend on the current behavior, whether that makes sense or not; and forcing users to understand coherence (which instance is used by which code) is almost always a giant impediment to getting users to like your language. Hence, "orphan rules", and why everyone hates Scala 2 implicits.
That said, I would love to see a solution in my favorite class of solution: where library authors can use and benefit from this, but the average user doesn't have to notice.
I tend to think that the non-existential Scala system was _so close_, and that if you _slightly_ tweaked the scoping rules around it, you could have something great.
For example, if - as a user - I could use `.serialize(...)` from some library and it used _their_ scoped traits by default, but if I _explicitly_ (named) imported some trait(s) on my side, I could substitute my own, that'd work great.
You'd likely want to pair it with some way of e.g. allowing a per-crate prelude of explicit imports that you can ::* import within the crate to override many things at once, but... I think that with the right tweaks, you could say 'this library uses serde by default, but I can provide my own Serializer trait instead... and perhaps, if I turn off the serde Cargo feature, even their default scoped trait disappears'.
That was my first thought! I never had this problem with Scala (2.x for me, but I guess there's similar syntax/concepts in 3).
The article author does talk about naming trait impls and how to use them at call sites, but never seems to consider the idea that you could import a trait impl and use it everywhere within that scope, without extra onerous syntax.
Does this still solve the "HashMap" problem though? I guess it depends on when the named impl "binds". E.g. the named Hash impl would have to bind to the HashMap itself at creation, not at calls to `insert()` or `get()`. Which... seems like a reasonable thing?
> When something near the bottom needs work, should there be a process for fixing it, which is a people problem? Or should there be a mechanism for bypassing it, which is a technical solution to a people problem?
I don't think it's a people problem in the way we usually talk about the folly of creating technical solutions to people problems.
If something like serde is foundational, you simply can't radically change it without causing problems for lots and lots of people. That's a technical problem, not a people problem, even if serde needs radical change in order to evolve in the ways it needs to.
But sure, ok, let's imagine that wasn't the case. Let's say some new group of people decide that serde is lacking in some serious way, and they want to implement their changes. They can even do so without breaking compatibility with existing users of the crate. But the serde maintainers don't see the same problems; in fact, they believe that what this new group wants to do will actively cause more problems.
Neither group of people even needs to be right or wrong. Maybe both ways have pluses and minuses, and choosing just depends on what trade offs you value more. Neither group is wrong about wanting to either keep the status quo or make changes.
This is actually a technical problem: we need to find a way to allow both approaches coexist, without causing a ton of work for everyone else.
And even if we do run into situations where things need fixing, and things not getting fixed is a people problem, I'd argue for this particular sort of thing it's not only appropriate but essential that we have technical solutions to bypass the people problems. I mean, c'mon. People are people. People are going to be stubborn and not want change. Ossification is a real thing, and I think it's a rare project/organization that's able to avoid it. Sure, we could refuse to use technical workarounds when it's people we need to change, but in so many cases, that's just running up against a brick wall, over and over. Why do that to ourselves? Life is too short.
Having said that, I totally agree that there are situations where technical workarounds to people problems can be incredibly counter-productive, and cause more problems than they solve (like, "instead of expecting people to actually parent their kids, force everyone to give up their privacy for mandatory age verification; think of the children!"). But I don't think this is one of them.
That's a generic problem with oil states. Or, more generally, where most income is generated by some centralized industry with strong government involvement. See "Dutch disease".[1] It's a strange situation in which having high income from valuable resources ends up making a state less industrial, and usually both more corrupt and poorer.
Is AI going to do this? Quite possibly. One of the symptoms is most investment capital being sucked up by the extractive industry. We're there now with AI. The
current US situation is that the economy is flat except for AI companies and data centers, which are booming and are sucking up vast resources.
Most of OPEC has been through this cycle. Venezuela, Egypt, Iran, Iraq - lots of oil, but it didn't make the countries rich.
It's becoming painfully clear that we have no idea how to run a society where machines do most of the thinking.
Maybe there will be a glut of smart people. Historically, that was the case until roughly WWII. Humans produced a certain fraction of smart people, but there were more smart people than jobs for them. Pikkety points out that through most of history, about 97-98% of the population was doing manual work. That started to change with the Industrial Revolution. Not until roughly WWII did an actual shortage of smart people develop. Hence the postwar boom in college education. Not until the 1990s did the nerds take over.
We think of a large group of smart people making society go as normal. Historically, it wasn't like that. The robust, the entitled, and the religious were in charge. Pikkety has a long analysis of this in his Capital and Ideology. Look who runs the Trump administration.
We're already at a smart people glut. In the US, only about half of college graduates find jobs that really need a college education. That's pre-AI. Now what?
> > My technical skills are being disrupted by machines - that's fine I'll go do other things.
> As others have noted, it's great to not actually need the paycheck you are working for.
Um. Yes. There's a link on "other things". It's to a site for a bike tour. The author seems to be implying they don't really need a job.
I still remember hearing a group of homeless people near the cable car turntable at Powell and Market in SF talking about the days when they used to be printers. That was, for several hundred years, a stable, well-paying job.
We really need automated roofing. Installing shingles is easy, except that it has to be done on top of buildings. There's an experimental roofing robot, but it's not good enough for production yet.[1]
Metal roofs seem nice and easier to install too, but at least where I had a house built (Ireland) the local planners (aka meddling old people with too much time) thought it wasn’t suitable for a “home” so you had to spend four times as much on a slate roof.
I never answer my land line with "Hello", because predictive dialers recognize that as a go signal for telemarketers. I usually answer my land line with my name, business style. Cell phone is answered with "Hi, ... " depending on who's calling.
Also note that if you buy a Tin Can unit, there's a noncompete clause: You agree not to "build, benchmark, or develop a competing product or service." So don't buy this if you work for a telco, or a voice communications service of any kind.
If a company puts unenforceable terms in their TOS, how likely are they to comply with the law in every other matter? No way would I give my kid a device made by these people for that reason.
I literally LOLed at the idea that purchasing a consumer product, at retail, could include stipulations on my future employment. And at the hubris of any manufacturer for imagining they could get away with such an absurd idea.
[1] https://newsreleases.sandia.gov/always_never/
reply