This experience makes me suspect that there will always be some pain point with the language. We'll never be happy; that's impossible. The only thing we can do is choose what type of unhappiness we are willing to live with.
The thing I love about Go is its fundamental clarity. It's very upfront and literal. I find it easy to understand what is happening in any particular bit of code. And I suspect that whatever complexities we add would compromise this clarity in the name of brevity. I'd spend less time being bored, and more time being puzzled or incredulous. And fundamentally, I'd rather be bored.
Won't dispute that but did that materially affect your chosen paradigms and patterns?
If you compared modern C# to C++03, then maybe (although even then I would argue that templates alone are more complicated still).
Not that I ever had this sentiment but even if so: why would you try to do that? Most new features are tiny enhancements you can live without and the big changes (generics, Linq) you cannot do without so you they are forced anyway. ‘Trouble’ sounds like you were actually bothered by it which seems a bit over the top?
The only problem I have with it is it is still really Windows only, hopefully that will improve with .Net Core 3.
Maybe you are talking WPF / Desktop only; there are other options for Mono but yes, there you would be right. However the trend is, unfortunately, toward browser interfaces (Electron etc) and those you can do on Linux/Mac already with .NET Core.
I wasn't thinking of Desktop although I would love to see something strong emerge there (other than Avalon).
Ah, curious what made you feel that. We ported massive code bases of ASP.NET and commandline tooling over to .NET Core since the 1 and had not many issues. It's a much better experience now but it never felt unfinished to me.
I have to admit that I have been writing software for a long time and one of the things I automatically do is abstract (not too far, just far enough) the underlying implementation of whatever I make/made. So our old ASP.NET code was very easy to port for that reason; I never use internals directly and still do not. For instance MVC looks more or less the same anywhere so I just use plain old C# classes as controllers so they can be reused by apps, other (non ASP.NET) frameworks, commandline, tests etc. It adds a thin layer below them so they work but it saves a lot of time and with the coming of .NET Core it proved smart once again.
I'm developing a C# application on Windows (netcore 2.1) and it deploys and runs on OSX without a glitch.
I've been writing games in C# that run on Windows, Linux, OSX, iOS, Android, Windows Phone, UWP, AppleTV, Nintendo Switch and more for years now.
Ironically, the most compatibility issues we had was with Windows Phone and UWP.
I really appreciate what I've seen of both Rust and Go myself. They both feel more approachable than the C/C++ legacies imho. Though I haven't gone much farther than general tutorials with either.
When reading Go codebase I'm not familiar with, I'm very often having a hard time figuring which interfaces go with which structs. As in "Oh, this function accepts interface Foo, which is implemented by which structures?" and then I have go on a adventure throughout the codebase to figure out what structures go in there. Really annoying.
In a language whose intention is to be explicit and easy to read (as opposed to write) I can't understand for the life of me why the authors chose to make interface implementations implicit. It seems like a decision that pretty much only has downsides and which is contrary to the overall aim. I just don't get it.
Suppose Bob's codebase has a structure implA that implements interface A, and you want to use in terms of its interface. If the language requires Bob to declare implA as an implementation of A, you have to persuade him to do so in his codebase. But if implicit implementation is enough, then you can just use implA directly as an A with no changes by Bob.
But yes, this is a sore point. It would be convenient to be able to declare structures as implementations of particular interfaces, even if the current implicit behavior were preserved.
Not necessarily, in some lanugages you can add an interface to type even if the type is foreign and you only control the interface. I believe this can be done in Swift, Rust, F# and quite likely some others...
Strangely, I feel the day Go has generics is the day its attractiveness will start to fade away.
You won't find hundreds of purported simple/easy things that are exclusive to Go code.
There's probably less than 10 cases where I implemented some simple thing (like a set of strings) that Java gave for free because of library function that used generics.
Among 50k loc that's background noise.
from README:
// ... use session session.Close()
can be changed to this right after you get a session:
defer session.Close()
This is precisely how I feel, could never capture it in words myself.
Sounds like JavaScript/Node all over again, which shouldn't surprise anybody as many of the prominent Node developers hopped over to Go.
a = append(a, el)
pop: n := len(a)
el := a[n-1]
a = a[:n-1]
It took me, literally, 10 seconds to write.I looked it up and it's not but the point is that you shouldn't have to worry about these things, including implementation details of trees and hundreds of other data structures.
I don’t think I will ever understand why so many go advocates seem so openly hostile to encapsulation. If go had used C-style for loops, I swear there would be people here defending the decision saying:
sum := 0
for (i := 0; i <= len(a); i++) {
sum = sum + a[1]
}
“See? Only four lines. What’s the big deal? It took me literally thirty seconds to write.”Compared to
array.sum()
was the above code more or less clear? Is it more or less prone to bugs? When reading, which code will you have a quicker understanding of the intent?And if you did notice the the first bug, did you notice the second bug?