Tai Chi is interested. It's essentially a standing form of yoga.
IMO, in theory it's even more useful for desk workers than yoga.
If you look at the history of Ashtanga Yoga, it was primarily developed for the traditional life. Where even non-laborers spent a significant amount of time on their feet and moving around. This is why doctors, nursers, actors, laborers, retail workers, etc... sing praises about yoga. I struggled to get much out of it, as I found it stretched the stuff that wasn't that tight for me and didn't focus on my problem areas.
The martial arts background of Tai Chi, alongside the pivot to longevity focused practices in East Asia, makes Tai Chi uniquely suited to the woes of a desk worker.
Unfortunately Tai Chi lacks serious standardization or centralization, so it's hard to know if a particular school/class will work for you nor is it as easy to self-study.
Of course, you don't need the Eastern traditions to obtain these same benefits. Dynamic stretching, Pilates, and functional strength training can work too, but I find that the eastern stuff has a meditative/spiritual aspect that regular training does not.
I don't know if anything has changed, but last time I tried codegen for Common Lisp, the LLM would routinely mix up LISP dialects and language specific features.
I've been using LLMs for Common Lisp since Sonnet 3.7 and have never experienced that. Did you have a mixture of other lisps nearby to confuse it? Seems like an odd failure mode.
This is an inevitable result of small dataset size. As recently as the start of this year, flagship models struggled with Objective-C unless the target was Apple's latest API. (This is per GNUstep lead dev Gregory Casamento, who has every reason to be an expert in these things.)
Even if you're not both typing at once, being able to trade off quickly without having to manually pass the ownership back and forth has had value for me in the past.
This feels a bit like asking why I would send my coworkers a Slack message instead of an email. For some things, send and wait for them to look at it is fine, but if I want to have a conversation, it's a lot less work to use something that's real-time. If we're both working on nice modular features, and they just need to use the code I wrote as-is (or only make some small targeted changes that they can do without my help), git branches are useful. Sometimes it's been useful to be able to prototype something in real-time while bouncing ideas off each other or if I'm trying to help them get something specific working in their code (but I don't have nearly as much familiarity with the other parts of what they're doing).
>> why do you think Go is better compared to other languages?
> I didn't say that. :)
I call this the Go paradox.
I simultaneously believe we should reach for it 80% of the time to solve common collaborative problems. And being a poorer language is actually an asset in these cases.
However, in doing so, we get rusty lose our fluency in more expressive, perhaps even better languages.
The beauty of go is YAGNI. Language design makes it much harder for people so do stupid and cute things.
During my design process if I start realizing that I’m missing maps, More expressive Types, Or more complex polymorphism. I ask myself if I really need those things.
If I really do. I move off of go.
That’s the beauty of the language. Go does not need more complicated language features because it’s can handle the majority of trivial software work without unnecessary complexity.
The language does not need to solve complicated problems.
Ok, and what if you realize you want these things a million lines in? Do you still move off of Go?
Generic programming isn’t some fancy research language feature like dependent types. It’s just a bare minimum feature in any modern typed language.
It’s perplexing that after C# and Java both notably shipped without generics initially then added them later that they decided to ship Go without generics.. only to end up adding them later.
I guess it's possible that C# and Java taught the wrong lesson (you can add this later) and that actually reduced the impetus to ensure Go shipped generics in 1.0
It is also entirely fair to say there's a lot of complexity here and so there's a risk you exceed your complexity budget which for Go as I understand it was very slim. It is a possible a Go 1.0 with more generics doesn't take off because too many people bounce off the extra complexity and so a decade later it's an obscure thing Google made once that has a few fans but not much adoption.
Or that extra complexity means Go 1.0 ships five years later, after Rust 1.0 has given people an appetite for better performance and better safety and its sharpest corners have already been knocked off.
From what I've seen, I don't think the core Go team was ignoring the lessons of Java or C#.
Here's a sample quote from Russ Cox from 11 years ago on this site: [1]
We have spoken to a few true experts in Java generics and each of them has said roughly the same thing: be very careful, it's not as easy as it looks, and you're stuck with all the mistakes you make. As a demonstration, skim through most of http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.ht... and see how long before you start to think "was this really the best way to do this?"
And of course, they asked other experts for help, including Philip Wadler (of Featherweight Java and Haskell fame): [2] [3]
We’ve been thinking about generics since work on Go began, and we wrote and rejected our first concrete design in 2010. We wrote and rejected three more designs by the end of 2013. Four abandoned experiments, but not failed experiments, We learned from them, [...]
Last year [2018] we started exploring and experimenting again, and we presented a new design [...] and we’ve been working with programming language theory experts to understand the design better.
FWIW, C# generics are way better (ergonomics) than the Java ones (due to type erasure), so Java waited too much. History is more complicated though for Java, since it was either having some generics vs having none. See [this](https://softwareengineering.stackexchange.com/questions/1766...) for a lengthier discussion.
Yes, .NET had the benefit of coming second and using F#, which was originally essentially OCaml 4 on .NET, as it's testing grounds. Same for Async
I am considering .NET for one of my compilers backends because of the reified generics. .NET can even pass around an object with generic methods that get specialized via JIT at runtime each time it sees a new data type (with reference types sharing implementations). Which also ties back to having true value types
It's a shame it took so long for .NET core to come around because even today the platform carries a reputation for being windows first which hasn't really been true for many years now
People always forget this other post when arguing for the home team.
"They are likely the two most difficult parts of any design for parametric polymorphism. In retrospect, we were biased too much by experience with C++ without concepts and Java generics. We would have been well-served to spend more time with CLU and C++ concepts earlier."
It doesn't seem particularly damning to me, though, especially written by Russ Cox in hindsight. It's almost a truism that if you had spent less time on approaches that didn't pan out and more time on approaches that did eventually pan out, you likely would have arrived at a workable solution sooner.
For example, if the core Go team had spent more time exploring C#-like approaches (as some suggest they should have), it's possible that would have delayed the whole thing.
(btw, consider me a "long time listener, first time caller" -- I pretty much always pause to read your comments while flicking through discussions here, including I appreciate you often bring in historical context, even if I might have a different take, or even if I might have expressed your take differently ;)
I'd welcome the ternary conditional operator but I hope exception handling never gets introduced (at least as I'm used to it from Java, C#, JS, etc.).
Exceptions should not be conflated with regular error handling, especially when they're allowed to bubble up from anywhere. I very much appreciate that functions that can return errors force the caller to deal with them, for the most part. True exceptions can already be thrown with panic, although I actually find it incredibly rare that I need to reach for that tool. I'd argue that when people talk about exceptions they almost always actually want "unhappy path" error handling.
Now, if Go wanted to add a sleeker way to handle those errors, similar to Rust's approach, I'd be very interested. Minimum three lines for every call to a function that returns an error does get a bit verbose, arguably hurting readability. A little sugar could improve readability without making error handling implicit.
Usually, if you're in microservices land, it's often possible to spin off a separate service and move the part that has different requirements over. Obviously that isn't always trivial, but service boundaries at least give you that option.
I had a team convinced that a particular subsystem was a mess and that they needed a stronger type system to build it properly because Go would just lead to hacks. They built a better one in Rust, deployed it, and moved traffic over.
Ditto, to some extent, if you're building desktop applications. Many large desktop applications already have multiple components or processes under the hood, and if you're at millions of lines, introducing that complexity may be worth it.
However, not all programs fit the above category. Sometimes you really do need a single lightweight binary and it needs to do a lot of stuff. But I think it's relatively uncommon to need one single binary that is simultaneously very large, architecturally diverse, and unable to delegate substantial complexity to other processes or services.
I see this most in the Kubernetes world, where something that starts as a simple binary gradually increases in scope and complexity. I've seen vendors struggle to keep up and start playing whack-a-mole with that complexity, but generally Go still scales surprisingly well here. Outside of K8s, there are also domains where you may strongly prefer a single-process or single-binary application, such as edge computing or developer tools.
Luckily, products where Go excels in these spaces also tend to have a natural upper bound on their domain complexity, because the operating model is generally about doing one or a few things well.
If Go's type system actually starts fighting you rather than merely being an inconvenience, then yeah, I would seriously look into moving off Go.
If you're working in a space that doesn't fit any of the above, I'd genuinely be interested in hearing about what you're building.
So your argument is that they should have gotten it exactly right first time and stuck to their guns?
I mean come on. The Golang team created a useful language people use for building real things — it’s easy to work with especially on large teams, and when the lack of generics turned out to be a pain point in the end (after years of production reality) they understood what the community wanted and actually… added them..
Now what, it’s not good enough?
No one forced you to use go.
No programming language is perfect. I personally find the language has served me well.
And after being so very pro generics myself, i actually find myself not even really using them that much apart from calling the slices module etc which has them under the hood anyway…
Nope, I’m saying that the language that was seemingly designed with either an ignorance of or disdain for the hard-won lessons from decades of prior programming languages.
There was even this condescending attitude that Google engineers couldn’t understand fancy languages anyway, so they had to dumb Go down.
My criticism really isn’t even about Go itself. Yeah it’s improving, which is great.
My criticism is about this anti-intellectual attitude that has permeated the entire Go community since its inception. It’s like hearing that college is a waste of time from people who never graduated high school.
Go only took off thanks to Docker pivot from Python into Go, and Kubernetes from Java into Go, after the respective teams got some Go folks into the project.
The usual RIX approach, followed the whole devops hype cycle that created all those CNCF projects half of which no one in devops space actually knows they exist.
perhaps, but chromebooks still come in laptop sizes these days. Other than a few stragglers (e.g lenovo duet), the majority of chromebooks are 12-14 inches.
If you are chasing the form factor, macbooks are serious competitors with really good battery life and tactile feel.
The beauty of netbooks was that ~10 inch form factor. Really the perfect companion device without needing a special bag to carry.
In many ways netbooks were a over a decade too early, and came right before the mobile hardware computing boom.
Netbooks are still not feasibile today, modern web design has made smaller lower res displays completely unusable today.
Tech Companies are trying to push foldable phones and tablets into this niche - but there was always something nice about a keyboard.
Am I the only one who dislikes Go specifically for CRUD webapps?
I’ve worked with Go professionally for the past 5 years, and I genuinely like the language. I like the anti-framework philosophy, the simplicity, the resistance to over-abstraction or even worse... bad abstractions, fast builds, the light native binaries, and how easy it is for a team to converge on idiomatic code.
But the moment you’re building a normal product app, even “basic CRUD” is rarely just CRUD. You need a database layer, migrations, auth, validation, maybe an OpenAPI spec, background jobs, admin flows, maybe server-side rendering, maybe GraphQL, etc.
You can end up with a large codebase full of repetitive boilerplate for an app that does not actually do much conceptually.
Maybe some people see a large codebase and feel accomplished, but just because each line of code is readable doesn't mean you know what its doing.
agreed, ultimately claude is faster than an expert K8s in my org at finding things. kubectl has a lot of commands and things to cross-reference. AI Agents handle it like a champ.
That being said, Claude is dumb. I've seen it over-complicate diagnosing things - even though it's initial theory was correct.
I am convinced a good harness can solve this.
Outside of the k8s operating model, I don't see the point of becoming a wiz at the CLI. I learn by practice and I atrophy if i do not practice, there's no world where I will get enough practice to do it on my own anymore.
I compensate by trying to either move up or down the stack depending on the problem.
IMO, in theory it's even more useful for desk workers than yoga.
If you look at the history of Ashtanga Yoga, it was primarily developed for the traditional life. Where even non-laborers spent a significant amount of time on their feet and moving around. This is why doctors, nursers, actors, laborers, retail workers, etc... sing praises about yoga. I struggled to get much out of it, as I found it stretched the stuff that wasn't that tight for me and didn't focus on my problem areas.
The martial arts background of Tai Chi, alongside the pivot to longevity focused practices in East Asia, makes Tai Chi uniquely suited to the woes of a desk worker.
Unfortunately Tai Chi lacks serious standardization or centralization, so it's hard to know if a particular school/class will work for you nor is it as easy to self-study.
Of course, you don't need the Eastern traditions to obtain these same benefits. Dynamic stretching, Pilates, and functional strength training can work too, but I find that the eastern stuff has a meditative/spiritual aspect that regular training does not.