Hacker Newsnew | past | comments | ask | show | jobs | submit | dualvariable's commentslogin

The flip side is that the US isn't used to fighting anything other than asymmetric warfare / insurgencies / terrorism against people who can't project force and can't really hit back. We park valuable assets out in the open on military bases and installations around the world, and don't do anything to shelter them or even move them around during a conflict because of hubris.

Iran also basically just fought us to a stalemate, with an arguably long-term strategic victory going to Iran, just by being willing to absorb more punishment in the short term. Once we depleted our stocks of expensive weaponry we had to stop. We could win every fight and still lose the war.


> Iran also basically just fought us to a stalemate, with an arguably long-term strategic victory going to Iran, just by being willing to absorb more punishment in the short term. Once we depleted our stocks of expensive weaponry we had to stop. We could win every fight and still lose the war.

Iran had a different victory condition. All they had to do was outlast and not be completely wiped out. Trump's victory condition was... well, only Trump knows. Short of a total ground invasion of Iran and full eradication of the Iranian regime (a tall, tall order), victory for the US in Iran, in the eyes of the public, was always going to be impossible.


Trump seemed to think that the Iranian regime was unstable and would fall once the US killed their top ranks and applied a bit of pressure. Turns out that he was very wrong (and experts would have told him if he had bothered to ask / listen).

I think its poignant to point out that Trump is listening to experts he appointed, who by objective standards do not have the experience or maturity necessary to guide the ship.

This is a war that even the "forever war" US military-intelligence complex had been resisting starting for decades. This really illustrates what a colossally bad idea it was.

You don't really need to be ferrying quarter million dollar horses to Europe to enjoy having horses. If you're not in an HCOL area, and not doing anything remotely fancy, you should be able to keep a horse for around $1k/month if you have a few grand buffer for vet emergencies, and you're not buying a lot of tack, equipment or supplies. You need to be into horses for their personalities, though, and willing to take on older/rescue cases, and not have fantasies of Olympic competition.

I'm particularly glad the Touch Bar got "killed by Apple".

Yeah, this is why I'm not a Libertarian. Concentrated power in the hands of single individuals impacts the freedom and liberty of everyone else. That holds if the person is the head of government, or the CEO of a corporation.

> if err != nil is the feature, not the bug. It forces you to look at every place something can go wrong and decide what to do about it.

No it really doesn't. It litters your code with if statements that are all just about the same, except that one that needs to be different, and you go blind looking at them all and can't spot the difference. And these days people probably just type "tab" and their LLM assistant fills out the entire block incorrectly in one keypress copying the pattern from everything else.

But LLMs didn't create that problem. Having to type something never meant you had to think about it, or thousands of "sudo shutdown -r now" commands would never have been run on production databases, because typing "sudo" would have magically made someone think about it, rather than just being keyboard memory.

And the problem of reviewing the code and spotting the one error handling block that should be different from all the others is always going to be there for human reviewers.

Rust converts the common case boilerplate down into one character: ? which lets you focus on any exceptional error handling rather than a wall of if statements that almost all look alike. And the compiler can see that you're ignoring a Result from a function call and force you to explicitly do something about. Plus you can then use a monad without knowing a single thing about monoids, endofuctors or category theory, and impress your friends.


> No it really doesn't. It litters your code with if statements that are all just about the same

Wrong thing to be bothered with. This allows static analysis of every possible path the code can take. Try to do that with throw/catch. There is a reason many industry guidelines like misra, jsf, etc just outright ban hidden paths. They have been literally catastrophic. There is a reason why many modern languages like go, rust, etc, want errors to be explicitly handled.

Go documentation specifically reasons why they treat errors-as-values and why is it like that - https://go.dev/doc/faq#exceptions

> Rust converts the common case boilerplate down into one character: ? which lets you focus on any exceptional error handling rather than a wall of if statements that almost all look alike

Again, wrong way to look at errors. Errors are not a problem for a compiler to resolve. Errors are part of your business logic. They need to be explicit and handled. The syntax of one language vs another is not the point of error handling. Errors are not a distraction. It is your job to review each path the code can take.

Code may be written once, but code is always reviewed or audited or referenced more than once. No one is impressed if you write some meta magic one-liner. I would rather be more impressed if I can read your code and form a mental image on how many paths your code takes to achieve an outcome in a single sitting, instead of pinging you for a quick call to explain yourself.

> you go blind looking at them all and can't spot the difference

> And these days people probably just type "tab" and their LLM assistant fills out the entire block incorrectly in one keypress copying the pattern from everything else

Now, if someone is 'going blind' looking at error checks, its because their function is doing too much and has too many failure points. Perhaps one may need to focus on honing their software engineering skills on how to structure their code, instead of hitting that 'tab' more so often.


Go has plenty of hidden code paths in defer, panic and recover. You can minimise the use of those things, just like in other languages you can minimise use of try-catch in favour of a Result sum type, which is already better than Go's "multiple return that you have to pretend is a sum".

Which is what should be discussed about go, rather than if-err clauses. That is hardly an issue in go. But Go has these little quirks which, if not careful, can become a problem. But instead most go critiques discuss only the error handling syntax. Look at the other comments.

The article is on point on the strengths of go, and in many cases, those other languages you say, you will find it really hard to do the same thing with the ease with which you can do in go.

What the article glosses over, is the footguns with working with the language. No compile time nil checks, implicit interfaces, lack of sum types, like you said, which more so often leads to bloated structs, member visibility which is just private and public. You can find more.

But these problems were not the main focus of go. Go was build because google devs wanted a simpler way to manage and deploy their software across thousands of services, not having to wait forever for their code to compile, not worrying about writing cpp code in the BEST possible industry standard, ability to do parallel processing of hundreds or thousands of workloads without choking your cpu, managing dependency hell. These were actual roadblocks. And google was not the only one facing these problems. Go solved all of it. Which language was solving this before go?


Go was developed because two UNIX guys, and one Oberon guy, that didn't like C++ decided to create their own thing, and their manager decided to support them as their 20% project.

Nothing else.

The narrative of Google wanting Go never happened, it gets sold as such by many Googlers.

Even Kubernetes was originally written in Java, before some Go folks joined in and drove the rewrite into Go, which besides the Android build system are the only two key projects using Go.



Yes, and?

Most of that was written by the Go team, not Google management, and even has the famous Rob Pike take on it.

The You Tube download rewrite from Python to Go, wasn't a management decision, rather yet another case of Go team taking language marketing into their own hands.

You will find posts from me on golang-nuts pre-1.0 days, as I was hopeful it would turn out differently back then, so I don't need education on how Go came to be.


> Most of that was written by the Go team, not Google management, and even has the famous Rob Pike take on it.

I am unable to understand your point or you seem to be making arguments that have nothing to do with the article nor with my earlier replies. I wonder why. Are you expecting sundar pichai to announce golang to his shareholders in his quarterly call? Which language does that?

This article and my replies are technical in nature. You need to have a technical response to a technical problem. You cant get emotional everytime. Which language allows me fast builds, lightweight and high performance concurrency, strong stdlib and tooling, easy cross compilation with static binaries, simple syntax, decent performance and by that i mean not worrying too much on memory management, easy onboarding and large scale maintainability? I am willing to try that tool.


Because your narrative is wrong, it wasn't a Google project, it was a group of Google employees that rebeled and were lucky to have their line manager support, given being UNIX idols.

Google upper management was, and is, perfectly fine with Java, Kotlin, C++ and Rust, for the most purposes.

I won't suggest any "technical" answer, because clearly you only want Go.


> I won't suggest any "technical" answer, because clearly you only want Go

You can’t provide me any technical answer.


I agree with all the motives you describe, yet come to the exact opposite conclusion.

The overwhelmingly common case is for an error in a nested call to be bubbled up to be handled by a parent call. If you make this common case look similar to the distinct case of actually handling an error, you just obscure where the real error handling happens.

Writing good error handling is Go is really hindered by two other issues mixing together: 1. There’s no Result type, so while it tries to treat errors as values, it’s missing out on a lot of the benefit of that idea. 2. Multiple function return values are implemented as a special case, and aren’t themselves a value

Most languages that support multiple return values, do it via some notion of tuples: returning a single aggregate value that you can pass around as a whole, but that also have some nice syntax for destructuring them into local variables. Go implements as a syntactic special case.

You can’t assign the multiple return values of a function call into a single variable. You’re forced to take all the parts, and pack them into a struct yourself. This means that you can’t factor your result-handling logic into testable functions, without needing to do this dance at every call site.


> No one is impressed if you write some meta magic one-liner.

I am very impressed if they can express the entire algorithm succinctly with a one liner. That's the kind of abstraction every piece of code should strive for and be shamed to the ground if they haven't.

> I would rather be more impressed if I can read your code and form a mental image on how many paths your code takes to achieve an outcome in a single sitting, instead of pinging you for a quick call to explain yourself.

Does this mean you're impressed by the ability to read go's if spaghetti?


> if they can express the entire algorithm succinctly with a one liner > That's the kind of abstraction every piece of code should strive for and be shamed to the ground if they haven

This obsession with one liners is inversely proportional to professional experience.


> This obsession with one liners is inversely proportional to professional experience.

Yes, I see this sentiment on every billboard. It is a sign of mediocrity.


> Wrong thing to be bothered with. This allows static analysis of every possible path the code can take. Try to do that with throw/catch. There is a reason many industry guidelines like misra, jsf, etc just outright ban hidden paths. They have been literally catastrophic. There is a reason why many modern languages like go, rust, etc, want errors to be explicitly handled.

I mean I'm explicitly supporting how rust does it over go, so I don't understand how this is any kind of rebuttal. In your last sentence you admit that rust enforces that errors are explicitly handled, and I think it does it much better than go does, and does it without littering the codebase with boilerplate if statements. The fact that you're launching into an explanation of the insufficiencies of throw/catch exception handling when that has absolutely nothing to do with what I was arguing... Well, I don't feel the need to argue with you any further. Rust also has errors-as-values and doesn't throw (at least not the common case, just like go), so the go FAQ on exceptions isn't relevant to the discussion.

And I'm just going to end the argument with that, since you seem to be a waste of time to deal with.


It’s insane that you are incapable of understanding anything I wrote. It’s even more insane that you seem to be unaware about evolution of error handling and why things are different in modern languages.

Study software engineering. Or study in general. Might improve your comprehension issues.


> No it really doesn't. It litters your code with if statements that are all just about the same, except that one that needs to be different, and you go blind looking at them all and can't spot the difference.

If most of your error handling is just bubbling the error up, you are doing something wrong.

  if err != nil { return err; }
is an antipattern. Not because it's verbose, but because you are supposed to handle the error, not pass it right through, in most cases.

The cops have likely been doing this for decades, because the human eyeball can confuse an O for a 0 much worse than image recognition does these days.

> "It's regular practice in Colorado to list license plates with both versions, the one with 'O's and the other with Zeros in the warrant list."

That is a suspicion of what might be the problem.

And he's facing a Kafkaesque problem that in order to get him removed from the list they need to know who the warrant is for, but he also can't find out who the warrant is for. Someone can clearly figure this out and help to get it fixed, but he's been unable to talk to a person that has the ability and authorization to query the system to figure it out for him.

We really need some anti-Kafka laws in this country so that if you wind up any sort of list like this, including bans from companies like Apple/Google/Meta/etc, that you have the right to know why and to appeal, and that they must not by default assume that you're a fraudster and refuse to speak with you.


>> And he's facing a Kafkaesque problem

Dont forget the comment from the local police...

"We can remove him from our list...we cant do anything about others list"


In companies, though, you often wind up with three+ massive dependency trees in your software to handle the same problem because people went and added the new hotness without deprecating the old stuff. You also find dependencies that are much heavier than necessary for the actual task at hand because the software developer was also solving the problem of needing that dependency on their resume. And then there's just the relatively tiny dependencies for fairly solved problems, like leftpad, which don't really require deps, and you can accept the maintenance burden, because not everything is an abstraction layer over chrome.

So if you just need to do something simple like fire off a compute heavy background task and then get a result when it is done, you should probably just roll your own implementation on top of the threading API in your language. That'll probably be very stable. You don't need a massive background task orchestration framework.

People might object that the frameworks will handle edge cases that you've never thought of, but I've actually found in enterprise settings that the small custom implementations--if you actually keep it small and focused--can cover more of the edge cases. And the big frameworks often engineer their own brittle edge cases due to concerns that you just don't have.

So anyway, it isn't as simple as "dependencies are bad" or "dependencies are good", but every dependency has a cost/benefit analysis that needs to go along with it. And in an Enterprise, I'd argue that if you audit the existing dependencies you will find way too many of them that should be removed or consolidated because they were done for the speed of initial delivery and greenfielding. Eventually when you accumulate way too many of those dependencies the exposure to the supply chains, the need to keep them updated, the need to track CVEs in those deps, and the need to fix code to use updated versions of those dependencies, along with not have the direct ability to bugfix them, all combine to produce an ongoing tax of either continual maintenance or tech debt that will eventually bite you hard.


I really wish they'd stop trying to suck up to me--all the "that's a really insightful question!" stuff.

I'm one of those aspy people who immediately don't trust other humans who try to fluff up my ego. Don't like it from a chatbot either.

But the fact that all the chatbots do it means that most people really crave that ego reinforcement.


You can already fix this in ChatGPT.

Settings > Personalization:

1. Base Style & Tone: Efficient

2. Warmth: Less

3. Enthusiastic: Less

I am amazed that people can use it at all without these changes.


Does that work in your experience? From what I see after a few rounds they go back to being incredibly annoying.

I dealt with frustrating software ,y whole life but LLMs are the only type that make me what to scream at it from actual anger


Well, it works perfectly for text based interactions, but if you try to do the thing where you can have a voice conversation with the robot, it doesn't seem to do much.

As a result I only try that voice once per new model release.


I do have to wonder what the mix is between "our data show this is how most people want to be talked to" and "these tokens lead to better responses on objective measures of correctness." That is, in the training data insightful questions are tangled with insightful answers, so if the bot basically always treats the user like a genius it gets on the track that leads to better answers.

Or yeah, it's just people being weak to flattery.


LLMs are only capable of thinking out loud, so in some sense this part of the answer is helping to convince it that it's answering a good question.

Same reason for the "That's not X, it's Y" construct. It actually needs to say that.

(Some exceptions for reasoning models.)


Yeah, I similarly doubt that LLMs are going to directly lead to AGI just via scaling and might almost be a dead end in that direction.

But they're still quite useful tools and accelerators or force-multipliers.

And you're still going to need humans in the loop.

And I'm very worried that the capex buildout will implode once we hit diminishing returns and good-enough models can be run on substantially smaller footprints.

It all isn't going away, though, and it will still continue to improve.


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

Search: