Go syntax is very cognitively demanding. Maybe I am getting old or have become used to C#, but between reading well formed go and C# code, C# always wins for me.
Go syntax is very cognitively demanding. Maybe I am getting old or have become used to C#, but between reading well formed go and C# code, C# always wins for me.
Go is very neat, true to its core identity and very very stable. I have been developing .NET (C# and F#) for almost 20 years and I don't enjoy it at all anymore.
EDIT:
Just last week the .NET team tweeted that they are looking to introduce green threads to .NET after all. I love the green thread implementation in Go and I think it is superior to .NET's async/await model which get scheduled by OS threads, but .NET has gone down that route many years ago and it's embedded everywhere now and introducing such a new fundamental change now is just plain fucking stupid. Microsoft is so dumb for even thinking this is a good thing to do. If they don't like how C# works then invent a new language with modern fundamentals which you like but stop changing C# so much that it's become completely unrecognisable. .NET developers don't want to rewrite their code bases every 12 months. We have real work to do.
Admittedly, a lot of it comes down to personal preference and familiarity with different technologies.
Though in regards to Go in particular, on a technical level:
- it's simple to build self-contained executables, it's up there with the likes of FreePascal in this regard
- it's also a relatively simple language that's easy to pick up and use, in contrast to how complex code can get with C# and Java
- it also has fewer footguns than C or C++ without the complexity of Rust (which some might prefer), although it doesn't try to do as much
- it has a decent community and lots of useful packages, even the included http libraries are nice to just get things done
- it doesn't have a history of challenging versioning and platform support, when compared with .NET (Windows only support with IIS for legacy projects, anyone?)
- the performance is generally good enough
All of that combined means that Go is nice for writing both quick utilities, as well as smaller and larger services alike. Just look at Nomad, a container orchestration platform, the executables of which can be shipped as a single binary: https://www.nomadproject.io/downloadsOverall, it's pretty good for just getting things done in a reasonable amount of time and a limited amount of headaches. For example, Python might lead to code that is easier to write and read, but packaging can be a nightmare. Java might be better for select enterprise systems, but configuration is generally a bit of a mess there. .NET is a good alternative, but some folks also try to steer clear of Microsoft and tooling on *nix can be limited, much like it is for Java (your best bet would be to use JetBrains commercial products, since MonoDevelop isn't all that popular anymore, Visual Studio Code plugins wouldn't give you a "full IDE" experience and there is nothing quite like Eclipse or NetBeans for .NET).
Further thoughts: the age of a language might also coincide with how loved or dreaded it is, since we simply don't see that many horrible enterprise monolith messes written in Go as of yet: https://earthly.dev/blog/brown-green-language/
Also doable in dotnet
> it's also a relatively simple language that's easy to pick up and use, in contrast to how complex code can get with C# and Java
Go is not a simple language. It has made choices of syntax that are baffling. Not to mention the mess that is exceptions and generics.
C# and Java, on the other hand, feel natural to read.
> it also has fewer footguns than C or C++ without the complexity of Rust (which some might prefer), although it doesn't try to do as much
C# is the same in this case. Far fewer footguns.
> it has a decent community and lots of useful packages, even the included http libraries are nice to just get things done
C# wins, but perhaps because it has been around for so long. But its ecosystem is very good.
> it doesn't have a history of challenging versioning and platform support, when compared with .NET (Windows only support with IIS for legacy projects, anyone?)
Things change, systems change, environments change. At present, C# and dotnet are truly cross platform and are amazing platforms.
> the performance is generally good enough
In Go, as your program size and team gets bigger, code management becomes harder. C#, along with Visual Studio is at its productive best, whether its with one developer or a 100 developers.
A trivial example of comparing the possible scope of any two languages in question, would be to glance at their lists of reserved words, for example https://go.dev/ref/spec#Keywords and https://docs.microsoft.com/en-us/dotnet/csharp/language-refe... However admittedly that's not a discussion that I have the time for, though I'm sure that lots of people here might share their own thoughts and experiences. Honestly, for web development, everything starting with .NET Core and the newer versions has been pretty cool, so it's not like you have to deal with the inherent complexity every day, unless someone gets a bit too clever.
Of course, less isn't always better, as certain other languages might demonstrate (a silly example, but still): https://en.wikipedia.org/wiki/Brainfuck
The only thing I cannot agree with here strongly is your argument about Visual Studio: I yearn for the day when Microsoft will finally port it over to *nix, but if you don't need to support it as a developer platform then you're in a pretty nice place to be! For everyone else, in the mean time, I guess there is Rider https://www.jetbrains.com/rider/ (though, of course, a paid product)
I never really understood this claim. Arguably, assembly is even less complex of a language, yet you would be hard pressed to say it is readable. Primitive primitives don’t necessarily result in readable code. For example a declarative description of what should happen with a stream of data is much more readable in many cases than 4 nested for loops with breaks and ifs.
But back to the topic, while there is a (fortunately getting less and less relevant) branch of Java which is very into needless abstractions, the language is a very small and easy to pickup one, allowing very readable and concise programs.
How often do you actually just use the core language without one of the frameworks, though? I guess it largely depends on what you do. For example, if you use Java for web app development, one of the more popular frameworks out there is Spring or maybe Spring Boot, which will force you to deal with a large amount of abstractions.
So while the languages themselves might not be that dissimilar, the ecosystems and frameworks/libraries around them, which actually shape how you'll use them most of the time (depending on the context), will most certainly lead to the differences being more pronounced.
As someone who's worked with quite a few (monolithic) enterprise projects, I couldn't disagree more!
The regular Spring framework can turn out to be a total mess of various intertwined .xml configuration files, based on whatever the project needs - access control mechanisms or integrations with external providers (say, LDAP or Kerberos), perhaps various filters for processing web requests (transformations, logging, additional flow controls), things to make any number of integrated libraries work correctly (JSR310 integration with Jackson, for example), all of which gets even worse if you need to get server side rendering in any of the older technologies working correctly, like JSF and PrimeFaces. You can get a variety of things done with Spring, true, but in practice it's going to be brittle and needlessly verbose.
The Spring Boot framework is a marked improvement, however you will still need a whole bunch of configuration in your .properties file(s), or maybe your YAML configuration if someone has opted to use that format. Of course, you shouldn't forget that you still need to figure out how to ensure that the profiles are loaded correctly and that you somehow haven't screwed up the settings in each file. But with Spring Boot, all of the sudden you need to also figure out which configuration related annotations you need and which ones could cause problems - how to better figure out passing DB connections to myBatis or Hibernate or whatever and also ensure that the session parameters are set as needed (say, default locale, so you don't get issues with Oracle).
Spring Boot simply takes a lot of the XML hell and turns it into a Java hell - better, because you're working with a proper programming language, but still not quite there yet, because a lot of the problems will only manifest at runtime (ever needed @Lazy with @Autowired?), which isn't fun when your app with thousands of source files takes minutes to start up so you can check everything out. Personally, I blame reflection and dynamic behavior for a lot of these problems, which is far harder to reason about than your IDE telling you that what you're attempting to write is weird and won't work before you launch everything.
Of course, my dislike of Spring is shaped by the utter messes of projects that I've had to work with, which is largely the inevitable outcome for any monolithic codebase that has to be kept around and is important to a business for close to a decade but also with limited resources (say, unlike the Linux kernel). That's also why previously I mentioned the "Green Vs. Brown Programming Languages" article - you tend to dislike some stacks once you've seen what long term projects in them end up looking like.
So, if you can, it's probably best to stick to smaller projects and microservices so these pain points don't become readily apparent and then most frameworks would be passable - be it Spring, Spring Boot or most others. Though I sometimes wonder whether people who wrote COBOL and FORTRAN also found starting out and having smaller projects to be enjoyable. Somehow we talk about languages and frameworks, but not how much of a difference there can be between a new project and an older one - some sort of a maintainability degradation coefficient that would express how maintainability changes over time.
I would even go as far and claim that the reason Java has this reputation of huge complexity in every monorepo is partly the effect of survivorship bias. Some other stack may have crumbled long before growing to such a monstrosity.
Nonetheless, I would also like to have more of compile-time DI, records, etc, but we shouldn’t just reinvent everything in a heartbeat.