But even more significant is that the Go authors cannot seem to grasp the importance of pre-existing conventions. Almost every language I've used in the past decade allows and encourages the variable, Class, CONSTANT convention.
It reminds me of people who want everyone to use CE and BCE instead of AD and BC, ignoring the inertia and relevance of the latter and almost seeming like we live in a vacuum where fresh ideas have as equal weight as old ones, and history doesn't matter at all.
I don't know how to explain this better, but this is basically the core reason I don't like Go, above and beyond any specific features or lack of features.
I once heard Go described as "what if we took the good ideas of C and started from scratch?" But it feels like they take that very literally, as if they were saying, "what if it was actually 1970 right now, and we didn't have C, and the next 49 years never happened?"
(This is a separate reply than my other one because someone already upvoted that.)
Funnily enough, Self opted for the opposite tack of not having private data fields (although it does have readonly and read/write slots), but you can trivially swap "data" slots and "method" slots: http://handbook.selflanguage.org/2017.1/langref.html#constru...
Most Smalltalk browsers do actually offer this capability
I realize that not everyone's preferred editor may support every language yet, but still I think the solution to this problem is probably just having the language designers provide libraries that editors can use for these refactoring features, instead of through specific capitalization conventions.
What "pre-existing conventions" do you see in the Go code that you've had to refactor? The fact that conventions from Java or C++ aren't the same simply reinforces the fact that Go is a different language, and that's A Good Thing.
I could see using it for CLIs and various Unix scripting, but I've been doing that with Ruby, for the most part. I also considered learning Go for creating some native binaries for a few critical paths, but Rust seems like the best choice for that. A NIF that crashes is one of the few things that will take down the Erlang VM, so Rust's strong safety guarantees (might) make it worth the steep learning curve.
My question was how the poster was using Go with Elixir. Since they have a big overlap in what they're commonly used for and since NIFs (Natively Invoked Functions) on the BEAM really need to be fail-safe, it's not as clear as how to use these two together as how one would use C in the same stack with Python, for example.
If the article had gone up to 250K connections, Elixir would have fallen down similarly to what happened to Node... although the reasons for Node being unable to keep up were unclear in the article, and I think warranted further investigation that the article didn't do.
For another comparison, feel free to click around on the tabs here: https://www.techempower.com/benchmarks/#section=data-r17&hw=...
The plaintext benchmark is about as far from a computationally intensive task as you can get... it should basically be network-bound, supposedly an ideal task for the BEAM VM, yet the results are clear.
If you turn on additional languages and frameworks, you'll note that Elixir or Erlang are significantly faster than, say, Rails, but Elixir or Erlang are a good 5x to 25x slower than Go.
People have built massive, successful companies on Ruby on Rails, such as GitHub, so don't think that I'm discounting these languages wholesale. You just have to accept that you will be paying substantially higher infrastructure costs if your infrastructure needs begin scaling beyond a single server. If you think that Elixir or Ruby or whatever else is the secret sauce to make your company successful, go for it! But those are a lot slower than Go or Rust or other very fast languages.
You can have that in Go as well, you just need to build all the clustering mechanisms, OTP behaviors, tooling, actor model, embedded monitoring services and such from the scratch. You may well see Go significantly slower than Elixir at this point when you finish baking all that into it.
Developer hours are significantly more expensive than hosting. I'd happily pay double for hosting if it meant I could need half the people to accomplish the same task.
...or just use kubernetes, to cover majority of those features.
Actually which of the above does Kubernetes really provide as it is in the Erlang VM?
maybe it's beneficial to someone, but I don't think that should be the default.
either way, it doesn't change the picture painted by the TechEmpower benchmarks.
However, the hypothetical benefit would also depend on the cpu model; it made a little more sense when they introduced it than it does now. Back then, CPUs took a significant amount of time to change power states, so going to sleep and waking up for an event that comes shortly after could involve quite a bit of delay. Even if the processor didn't fully sleep, it may reduce the clock frequency, and not increase it until you've done a substantial amount of work.
With more recent processors, these delays are much smaller, and perhaps it would have made more sense to control the power states in another way, but there was some justification.
From a lot of what I've seen, that is a useful description.
If you come to Java with a blank slate, and try using it with simplicity in mind. There's not much wrong with it. But once people add design patterns, layers of layers, reflection, annotations. Etc. You get a monster. And somehow, the enterprise world seems to always create those.
The one thing they should take away is namespaces. You can't write unreadable enterprise software if you can't put every 10-line class six packages deep for no reason.
Not exactly a novel take: https://dirtsimple.org/2004/12/python-is-not-java.html
- Compared to Java: Ecosystem is way over-engineered. You might get along just fine without writing a bunch of boilerplate and factories and XML configs, but sooner or later you're probably going to pull in some dependency that does and have to deal with a bunch of clunky APIs and other annoyances.
- Python: Possibly the only language that's even worse at dependency management than Go. Installs packages globally. The solution is to create a "virtual environment" which is code for hacking up your PATH.
- Node: I dislike the quirks of Javascript like remembering the difference between == and ===, undefined vs null, etc. I haven't used Typescript which may solve some of those language issues. I also dislike dealing with promises/callbacks for so many operations.
I like Go because:
- I can compile to a single statically-linked binary and cross-compile for other platforms
- I can choose to either vendor dependencies or use go-dep to create a dependency lockfile. I can have multiple GOPATHs with minimal magic.
- The "go" CLI handles pretty much everything I need without an explicit config file like pom.xml or package.json.
- The language lacks features. There is no magic. Way more so than even Python, there is one obvious way to do things and there's even an official style guide, so it's easy to jump into someone else's code and understand exactly what's going on immediately. After working with Scala professionally for a few years, I firmly believe this to be a feature, not a flaw.
- The standard library is incredibly comprehensive. It's completely possible to write a web service without importing a single external dependency. There has been a lot of thought put into library APIs for things like byte Readers/Writers and HTTP handlers, to the point that external libraries still usually stick to these standard interfaces. Contrast that with a language like Python where urllib sucks so everyone uses requests.
> == vs ===
Just never use ==, and you're done. This is pretty much a defacto standard. It essentially has no legitimate usecase that couldn't be expressed more explicitly with at most 1 extra line, and should just be ignored.
> undefined vs null
I've only very occasionally run into this being an issue. Standard seems to be using the falsey nature of both undefined and null to check for them, !x rather than x === null for example, so that it doesn't really come up much in practice, but anyway...
> TypeScript may solve some of these issues
Yes, it solves both the above :-)
> Dislike dealing with promises / callbacks
Firstly callbacks are hardly seen anywhere any more. And if they are, certainly no more than one level deep, and that's even assuming you don't just promisify the callback function anyway, which is trivial to do.
For Promises - async/await makes dealing with them syntactically much nicer in node. It's pretty much just like synchronous code to read, and in behaviour.
Which, I'm not sure there's a more durable reputation in all of informatics than Java's reputation for over-engineering things.
There are cleaner Java libraries for most things nowadays, but the culture around the language is also such that, in many companies, it is politically much easier to use another language entirely than it is to use Java but choose a REST framework that doesn't implement JAX-RS.
This might be true but I find it so backwards.
In comparison, the entire standard build process for a Go program is:
$ export GOPATH="/path/to/repo" && go get && go build && ./main
No config files with some DSL to learn or handwritten XML, no weird class loader behavior to track down, no tuning memory limits or any of that stuff that is just par for the course in Java.Like C/C++, javac is just a compiler.
It's not a a dependency resolver, a runtime, a formatter, etc.
go is all of those things.
And every time you jump into an existing codebase, you need to scrutinize the docs that are hopefully there to figure out particulars of the build/deploy process.
Look up libraries like Spark[1] or Javalin[2] and you get something quite light weight. Or DropWizard[3] if you need something more holistic.
That being said, the moment you need something more involved, say validation, DB access, pre- or post- endpoint call processing (e.g. for authorization), then golang completely falls on its face. There is nothing in golang that compares to Jooq[4] for instance, and because golang doesn't have annotations, you can't do automatic validation or authorization, and you end up having to do everything manually in a verbose and error prone manner.
For static compilation in Java, GraalVM is supposed to be quite good[5]
[1] http://sparkjava.com/ [2] https://javalin.io/ [3] https://www.dropwizard.io/1.3.12/docs/ [4] https://www.jooq.org/ [5] https://quarkus.io/
Also if you compare those codebases to Java (again enterprise) projects of a similar size they seem quite readable instantly..
That hasn't been my experience at an employer. Their devs mainly had Python and NodeJs experience and similar languages (which is what the first version of the code base was written in), and disliked "enterprisey" code. Somehow, the decision to move to golang was made.
Yet, they somehow managed to come up with their own mess, and yes it is mainly because how underpowered golang is. I keep thinking about how much simpler the code base would be if it were written in Java, let alone something like Kotlin.
Everybody has legacy code. Modern Java doesn't mean much if your team is 2 years away from being able to use the modern stuff.
As far as Python, same kind of reasons. Single binary makes deployments easy, static analysis and built in tooling makes life easier, and I just find it more enjoyable, which is completely subjective.
1. Java - did not want to adopt the entire ecosystem. This is very much wanted a banana and got the whole jungle with a gorilla type of story.
2. Python - dynamic. Don't want that. Go's minimal typing is perfect. It's easy to deploy (binaries). It's fast. It can scale well. It's opinionated (love this).
Python and Java both encourage and allow developers to flex creative solutions that are hard to maintain long-term. Sure, seniority helps with that, and being part of a good team; however using Go, you just run into that less due to the conciseness of the language and strong idioms.
I work on Golang stuff at work where we made the switch after the troubles associated with refactoring Python. Recently though, I 'typed' a personal project of mine that was fairly large, and it's become a pleasure to work on.
IDE integrations of mypy warn you as soon as type errors occur. The fact that the type annotations are first-class features of the language and not embedded in comments also makes it great. The compromise of type-safety at the boundaries where you interface with 3rd party APIs that don't provide type annotations (the major ones do) does not get in the way too often contrary to what I expected.
mypy makes Python a pleasure to work with again.
This is my experience as well. I love that I have the option to use Python typed and untyped. For little scripts, fiddles, prototypes, etc. it's often convenient to omit type annotations. For solid software that runs in production it's nice to have them.
Another thing that I'm excited about is nuitka [0], a Python to C compiler that allows you to create binaries from Python code. It cut start-up time of a command line tool that I compiled with in half.
Can you please provide some examples? This would be a useful comparison, as Java had way more time to work on the libraries.
Yeah it is tricky, but Java has a good track record here:
In 1.2 they added all-new Collections API. The old API is still there and still works, though it is not used much these days.
Then in 5 or thereabouts Collections API got generics.
Then in 8 or so, Collections API got streams, magical multithreading etc etc.
Lambdas were added to the language and standard libraries, and so on.
That being said, Go isn't perfect by any stretch. Sometimes panic ins Go routines can be very hard to trace. The transition to Go modules is challenging for larger projects with versions beyond 1.x (when I started it was Glide, then dep, now go mod, which has been a bit frustrating). However, I wouldn't go back to Java, C#, PHP, or NodeJS if I had the choice.
My go to in the server space is Go and Elixir. I don't feel a desire or need for anything else, but again, that's me. You know your use case better than a stranger on the internet :)