The trade offs are though that patterns and behind the scenes source code generation is another layer that the devs who have to follow need to deal with when debugging and understanding why something isn’t working. They either spend more time understanding the bespoke things or are bottle necked relying on a team or person to help them get through those moments. It’s a trade off and one that has bit me and others before
I am not talking about C# specifically but also and I agree.
Implicit and magic looks nice at first but sometimes it can be annoying. I remember the first time I tried Ruby On Rails and I was looking for a piece of config.
Yes, "convention over configuration". Namely, ungreppsble and magic.
This kind of stuff must be used with a lot of care.
I usually favor explicit and, for config, plain data (usually toml).
This can be extended to hidden or non-obvious allocations and other stuff (when I work with C++).
It is better to know what is going on when you need to and burying it in a couole of layers can make things unnecessarily difficult.
Would you rather a team move faster and be more productive or be a purist and disallow abstractions to avoid some potential runtime tracing challenges which can be mitigated with good use of OTEL and logging? I don't know about you, but I'm going to bias towards productivity and use integration tests + observability to safeguard code.
Disallow bespoke abstractions and use the industry standard ones instead. People who make abstractions inflate how productive they’re making everyone else. Your user base is much smaller than popular libs, so your docs and abstractions are not as battle tested and easy to use as much as you think.
Well the point of using abstractions is that you don't need to know the things that it is abstracting. I think the abstraction here is self explaining what it does and you can certainly understand and use it without needing to understand all the specifics behind it.
What are you working on that you're debugging annotations everyday? I'd say you've made a big mistake if you're doing that/you didn't read the docs and don't understand how to use the attribute.
(Of course you are also free to write C# without any of the built in frameworks and write purely explicit handling and routing)
On the other hand, we write CRUD every day so anything that saves repetition with CRUD is a gain.
It has been worth the abstraction in my organization with many teams. Thinking 1000+ engineers, at minimum. It helps to abstract as necessary for new teammates that want to simply add a new endpoint yet follow all the legal, security, and data enforcement rules.
Better than no magic abstractions imo. In our large monorepo, LSP feedback can often be so slow that I can’t even rely on it to be productive. I just intuit and pattern match, and these magical abstractions do help. If I get stuck, then I’ll wade into the docs and code myself, and then ask the owning team if I need more help.
I think that’s a bit of a stretch to say go will implement all the features of c# and Java because of a few new features. Go isn’t a frozen language, they just take a lot of time and discussion before committing to a major change.
The point isn't implementing all the features of c# and Java, rather doubling down on their simplicity mantra against all programming language complexity, only to revisit such decisions years later, because after all the other programming languages had good reasons to have such features in first place.
If you look back at the mailing list from earlier in the Go development you'll see that this was the plan. To start with as small and simple a set of features they felt was a necessary and evaluate more advanced features as the language evolved while trying to keep with the simplicity mantra when adding them. They wanted to evaluate the potential features in light of real work with Go.
I have a feeling that in the future developers are still going to be needed, but in an architecture and debugging/optimization fashion. Not in a writing boilerplate code aspect. There is also an issue with validating the output before it gets released to production.
Because most investors are investing in more than one company. If someone has a stake in Google, Microsoft, and Confluent, and their ROI for the first two are great this quarter, but Confluent is lukewarm or even in the red, they're going to want an explanation.
They can be told that products are great, or employees are producing a lot, but the only thing that matters to investors is the money. And so, when you're underperforming compared to others in your market, you have to do what appeases the shareholders, and that involves culling employees.
I have no unique insight into their perspective but if I had to guess they're starting to worry about the lack of easy money and want a signal that management is going to play it safe with their current cash reserves instead of banking on another infusion. They probably could, you know, tell them as much, but sacrificing your employees really adds oomph to your commitment.
If you hired employees to do something and they're making you money hand over fist, you don't fire them. They're not an expense. They're a profit center.
I think this one difficult subject does not take away from the common feeling that overall Go is simple. This is like looking at a small scratch on the car and claiming the entire car is damaged.
“Simple” means the definition has been kept compact, which should suggest problems went unaddressed. Gabriel’s “Worse is Better” essay reminds us that making a system do the Right Thing™ is rarely simpler.
But making the runtime go out of its way to store the exact type of an object you don’t have is damn weird. In theory a method could accept a nil receiver, but in practice they never seem to.
I've worked on tools that were slightly misnamed after 6 months, and completely misnamed after 2 years. At that point they were also usually just nearly useless due to feature bloat and/or lack of scalability, so deprecated or replaced with something better.
They didn't change names, but their successors would get a new one.
Isn't it even harder to re-define names in a company? There might be 3 people involved in re-definition, but it affects 15 people.
How are we going to notify those 15? Do we even know who those 15 are? Are we going to create a weekly redefinition newsletter?
I think in most cases new meaning deserves a new name. Everything else is just hacks.
How hard is it to change a name is a actually a really good metric for a company. If a simple rename takes several days, multiple approvals, rounds of QA, and a scheduled release next quarter, then you probably need those hacks.
I think that's very extreme. Products grow at a gradual pace. I don't think there are defining moments when a product no longer supports something, or is no longer used in a way that it was intended to.
I would argue it's easier to maintain peoples understanding of a product since that will also be done gradually. It's not easy to update naming inside of a code base without potentially breaking software significantly or causing unknown bugs elsewhere. I think most software would fail the renaming test. It's also generally not worth the money and time needed to make that change.