Take C# for example. The `System.Collections.Generic` namespace is full of generic collections (surprise!) that allow more type safe code. If I have a `List`, I can’t guarantee there isn’t something I don’t want in there (that could cause a runtime exception I don’t catch). But if I have a `List<IFeature>`, I know that everything in the list implements `IFeature` (barring compiler bugs and unsafe code).
One of the nice things about go is it doesn’t have many abstractions and most of them are carefully thought out. I don’t want to have to inhabit somebody else’s abstractions all day at work, I want the language to get out of the way, which go does quite well IMO.
Is this stockholm syndrome or something? For example, JSON.
Also, the time abstraction is completely bonkers.
If you want to multiply a 500 milliseconds with a user-given value (suppose I want some number of half-seconds), you must first cast the user value to milliseconds, then multiply, so you are multiplying 500 milliseconds times (say, 4 milliseconds) to obtain 2000 milliseconds.
And don't get me started on goroutines/channels. You are supposed to "share state by communicating" and not "communicate by sharing state". That's great. But at some level, you must bootstrap knowledge about the state of the channel, which is fundamentally shared state by the low-level nature of the channel. When you've worked in systems which have really thought out carefully what it means to have a no-shared-state system, the go system looks like it's been put together by either amateurs or fools.
JSON is not related to go but perhaps you have some problem with the JSON parser? Works fine me… Personally I don’t find the time constants a problem at all, I’m not keen on the time parsing layout, but that’s relatively minor. Channels I don’t have strong opinions about and goroutines if used sparingly I’ve found a nice balance of utility and simplicity for creating threads, but I recognise I’m not really qualified to argue about them.
Incorrect. You must cast the user value to a time.Duration, since Go is a type-safe language, and like most type-safe [1] languages, its numerical operations generally require their operands to be of the same type.
You might be thinking of multiplying a user-provided value by a constant (of type time.Duration) defined by the time package, like time.Millisecond or time.Hour. I’m under the impression this is a very intentional choice to require user-provided values to be explicitly annotated with their units. Some implementations/variants of durations use nanoseconds, some milliseconds, some seconds, and requiring this assumption to be explicit in the code helps avoid critical bugs like the Mars Climate Orbiter failure. [2]
The time package (and other stdlib packages) definitely has some warts, especially the time format parsing, but I’ve always appreciated the approach taken for durations.
[1] We could get into more advanced type inference here like Rust’s From/TryFrom traits, but the debate between simplicity vs. expressiveness in Go has been retreaded here tens of thousands of times and I doubt either of us has anything new to say on the topic.
When extremely motivated, I’ll script manipulation of the AST, but that’s a pretty extreme thing to have to do.
But this is of course orthogonal to generics, as you can make generics friendly to tooling as well, see Java.
And then the application grew and you have the guys who have to watch and keep the application online when it's business critical. They HATE abstractions. Because 7 abstractions that are used throughout the application means there's 127 cases the developer hasn't thought through, at least ten of them a ticking time bomb. That's 128 possible cases, one of which the developer has actually thought about, 5 they have verified to be reasonable.
An easy case to show what's happening is the suggestion every new developer makes. "I'll just have a thread per connection, that's easy". And yes, it's very easy to get it running. It doesn't block during dev, it handles multiple connections and generally does the job. And it's absolutely guaranteed to crash you server for 10 different reasons in production. And yet, every new developer will (and should) do it.
There's just 2 camps developers in the world, who don't agree and this won't seriously change. Learn how the "other camp" thinks and you'll do better.