doorman2
What we're seeing now is akin to the the dotcom boom / bust in the late 90s and early 2000s. A new technology has appeared on the scene which leads to two things:
1) People get ahead of themselves. In the late 90s, people could envision all the cool things the internet would unlock and tried to start businesses to realize the potential. Many of those business ideas would be viable today, but the tech wasn't there at the time leading to a lot of empty promises being sold. Today, people can envision how the blockchain will lead to the securitization of everything, but the tech isn't quite there to make the transition yet.
2) As with any optimism boom, there will always be crooks ready to separate a fool from their money.
[0]: https://www.sec.gov/Archives/edgar/data/1652044/000165204422...
What does that mean? The NYT sells ads, i.e. you can pay the NYT to have your advertisement shown in the NYT. Google sells ads, i.e. you can pay Google to have your advertisement shown in Google results. The NYT and Google sell the same thing. They are competitors.
int sfd = socket(domain, socktype, 0);
int optval = 1;
setsockopt(sfd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
bind(sfd, (struct sockaddr *) &addr, addrlen);
In Go, you can use syscall.SetsockoptInt. Most languages have a way of setting this option. You have to create the socket yourself and pass it into your HTTP server in most cases, but it depends on the library.Edit: oh sorry, you meant when systemd is opening the port for you. It looks like you can set ReusePort=yes in your configuration? https://www.freedesktop.org/software/systemd/man/systemd.soc...
This option is also quite good for deployments as you can have instances stop reading from the port while client traffic is still being served from other instances on the port. This works well for HTTP requests, but less so for something like gRPC.
Ultimately, the answer to your question is going to depend on what you want to make. For instance, if you want to make an iOS app, it's going to be difficult to do so without using Xcode's build system.
Go is a very good language in terms of having a build system that stays out of your way. On Linux, you'd do something like `sudo apt-get install golang`, and then be on your way.
We figured this out without needing to torture monkeys. Apparently, though, this was not sufficient for Harlow, as he created his pit of despair almost 30 years later.
The PTY interface in general feels a bit lacking. Normally, if you use a pipe, you can close to write end of the pipe to generate an EOF. With pseudo-terminals, you only have one file descriptor for writing input and reading output so you can't have the system generate an EOF without disabling your ability to read the output.
1) It's performant. The language itself is very fast, the GC is very fast and go routines make concurrency fast.
2) The tooling is great. Once you have the Go CLI installed, everything else "just works." Cross-compilation is super easy. Install dependencies is easy. Generating code is easy. Embedding files is easy. The ecosystem is really mature. Modules are easy to create, export, and import. Compilation time is fast. The list goes on...
3) The generics system is amazing. It beats any system that implements generics with type erasure.
4) The language itself is very easy to read and write.
5) The language is relatively new, which means less outdated cruft. The language also puts an emphasis on having only one way to do things.
So comparing it to other languages:
- Python: Terrible tooling. Not performant
- C# Bad tooling (do I need .NET, .NET Core, Mono? How do I create a project? What is this crazy project xml file? How do I export my project to be consumed by others? How do I import a dependency?). Also, as an older language, it has a bit of cruft, e.g. it has optional types, but they also aren't required? Maybe if I knew more about C#, I would find it better. But using it with Unity didn't leave a great taste in my mouth.
- JavaScript: not performant, especially in multi-core environments.
- Rust: Rust is too hard to write. It's not worth the overhead if you can afford a GC.
- C++: Same as rust, + more foot guns and unsafe memory management.
- Zig: Don't have much experience with Zig, but I'd like to.
- Ruby: Not performant, not typed.
- Swift: Tooling is bad. Compilation is slow. Cross-platform is not a priority. Swift Package Manager is buggy. Using Xcode sucks.
- JVM languages: bad tooling (maven, sbt, gradle are all a pain), generics have type erasure.
Of course, there are reasons to use other languages. If you’re writing an iOS app, the tooling for Swift is best-in-class. Or if you’re doing ML, the ML-specific ecosystem in Python outweighs all other considerations.
Caveats
unbuffer -p may appear to work incorrectly if a process feeding input to unbuffer exits. Consider:
process1 | unbuffer -p process2 | process3
If process1 exits, process2 may not yet have finished. It is impossible for unbuffer to know long
to wait for process2 and process2 may not ever finish, for example, if it is a filter. For expediency,
unbuffer simply exits when it encounters an EOF from either its input or process2.
Why does unbuffer care whether or not process2 exits? Can't it receive the EOF from process1, send it to process2, and then wait for process2 to exit? If process2 doesn't exit after receiving an EOF from stdin, then what's the issue about simply letting the pipeline hang? Isn't that what would happen without unbuffer?For instance, read the first sentence from Harlow's Wikipedia page:
> Harry Frederick Harlow (October 31, 1905 – December 6, 1981) was an American psychologist best known for his maternal-separation, dependency needs, and social isolation experiments on rhesus monkeys, which manifested the importance of caregiving and companionship to social and cognitive development.
Did we really need to torture these creatures for decades to understand the importance of care giving? The experiments seem like a flimsy pretext for torture.