Everyone I know who uses Go complains about it. Every day you write Go code you will come across some piece of code that would be shorter with templates in C++ or using <algorithm>, or you could do it more simply in Python, or if you were really clever it would be a single line of Haskell.
And yet we keep writing Go.
By comparison, I'm a bit put off by the Rust community's evangelism, but that might just be my personal experiences with Rust community members.
Often people are in all of those categories, they use what I see as marketing speech to talk about their own experiences. Those experiences might differ from mine so what I dismiss as parroting or marketing is later shown just to be difference in opinion.
I admire people who can spot such things effectively and steer discussions in an productive manner. I see now that this is not really about interviews anymore but just everyday discussions.
It's so prevalent our industry has a term for it. "Use it in anger". You know you've gotten to know a language when you have had to work around a quirk of it's semantics.
PHP has object checking. This is why I started using value objects in PHP.
The VO's I use trow exceptions when you construct them with some bad value.
This is great because when you use for example a natural positive integer object you are sure it is one.
So now I have 'type checking' and more secure code in PHP.
Since when does PHP has value types? Aren't all the classes reference types or you mean that Array thingie?
And it is still the case with type declarations, that they make your code actually slower, because the runtime adds asserts in your code which gets evaluated at runtime?
Runtime type checking while useful does not offer the same level of safety as compiler time. It will catch sinner classes of errors but you'll still have bugs lurking in production.
To be fair to the haters, even modern PHP can be horrible. The old nightmares are still around; we've just agreed to ignore them, and maybe deprecate a couple of the worst. (And ternary syntax is still broken, and the standard library is anything but standard.)
But yes, if you're working on a modern PHP project, there's a lot to love: A solid module system, an enormous sea of high quality libraries, type checking, a really nice deployment and scalability story, decent performance, good tooling (IDEs, debuggers, etc.), a servicable C-style syntax. For many purposes (not all!) it's ten times better than, eg, nodejs. (Which might seem like a low bar, I admit...)
nodets, as in typescript on node? I haven't personally tried it, but I imagine so, again depending on your particular use case.
I quite like Typescript as far as syntax goes, but I think PHP 7.1+ is comparable. And PHP has a lot more support, libraries, and better tooling in my view. For example, my experience in node land is there aren't really any good ORMs; PHP has multiple, including one (Doctrine) which is easily the equal in my view of the highly regarded Python SQLAlchemy. Similarly with routing, frameworks, templating, etc., there's a huge amount of maturity on the PHP side that's missing from node.
The big question is going to be in the process model. Node has an event loop; PHP doesn't. For most purposes, I think an event loop makes writing good code harder to no real benefit, but in some cases (eg, acting as the endpoint for a ton of open websockets) it can be a big win. If you do need that, then you should probably lean towards node over PHP, and sure, why not use typescript? But for the general case, I'd still lean towards PHP.
(Then again, there's also a ton of other languages and frameworks. Just because PHP - or node - might be better than the other for some task doesn't mean there aren't a dozen more languages better than both.)
In your view, if someone created an ORM for node which focused on creating object graphs for tables and fields (a-la sqlalchemy) instead of focusing on SQL building syntax (a-la knex) would it be popular?
I've been eyeing up Pony (https://www.ponylang.org/) a lot lately. To my eye, it has a lovely syntax and a very useful mix of modern programming features. I'm particularly enamored of the types, safety, actor model, and absence of exceptions. From a distance, it looks like the best parts of Rust, Golang, and Python.
> Haskel? Where are the libraries?
Well, I suppose the same drawback would apply to Pony. :)
Java, C#, F#, C++, D, Rust, OCaml, Haskell, FreePascal, Ada, Swift, Nim look all pretty fine to me, and yes there are ways to compile Java and .NET languages to native code just like Go.
As for libraries, what matters is if the desired use case is covered, not winning the App Store count.
What is your problem with Java?
What does "No thanks" mean?
It's interesting to hear your perspective, but hard to know what you mean if you don't write it.
(Also have you even looked at Scala, Kotlin, Groovy with static typing, and perhaps others?)
What libraries are missing? The only issue I've had with libraries are that some client libraries are wrappers over C libraries and this makes static linking difficult (or seemingly impossible on a Mac)
A few years ago there was a lack of libraries in some areas but that's not the case these days.
A slightly different perspective. For the end user Go apps are by far the easiest to setup and use. Usually it's just a single binary to download. That is a huge advantage that can't be beat.
Other languages usually need a large number of dependencies, with Ruby and Node, often an entire build environment, with plenty of potential for dependency hell and hours wasted.
Some may advocate containers at this point, but it just hides the issue temporarily and may be too much for a certain category of end users. You now need to know how containers, ports, volumes and Linux systems work in far more detail when you actually just want to use an app.
At least historically speaking, this wasn’t true. And the fact that it’s true today for Java and C# is an anomaly, since for most of the history of those languages native compilation was either third party, second-class with missing features, or both. Look at GCJ or Excelsior (commercial).
Or look at Python, which is also compiled. Or Ruby, or JavaScript, TypeScript, Dart…
With say a java app thou you'd typically get a .zip with all your class path dependencies and a launcher in one bundle. This is not the case for ruby, js (node), python etc where the norm is to splatter dependencies across your file system. Its not quite static linking but closer
This is not always true. Static linking with other language doesn't always have similar experience with Go. One of these is the compilation speed. With other languages you'll still have time to get a coffee break before its done.:)
In any case it doesn't change the fact that Go's compilation speed is nothing to brag about, it has been done before in many other languages, Turbo Pascal was just one example.
If you wish I can provide other examples of languages that compile as fast, on such old hardware while matching Go's compilation speed, with richer language features.
>Turbo Pascal compilation speed, in MS-DOS, using 90’s hardware was already faster than Go.
What relevance does this have on the compiler landscape today ?
If you have to use a compiler from ~30 years ago to find a comparison supporting your claim, it sounds very much like Go is indeed much faster than what it competes against today.
The relevance is that a compiler running in 90's hardware is able to beat Go's compilation speeds of 2017. That same compiler has evolved through the years.
If you want the 2017 version of it, it is called Delphi. Beats Go in language features and compilation speed.
Go's compilation speed only surprises those developers that never used anything else beyond C and C++.
> And beat 99% of other compilers today, meaning that overall compiler complexity has grown.
Which ones?
> For me (tm), Go compilation speed has compared equal or favorably against C, C++, Java, C#, Rust at least.
Since when does Go compile faster than Java and C#?
When I hit Ctrl+S my binary is already on the disk, thanks to incremental compiler integration on the IDE.
I have a full blown WPF application with multiple plugins, including data visualization, talking to Oracle and Postgres, total compilation time after check out 12s.
Eiffel, D, Nim, Jai are other fast compilation examples.
Java isn’t required for the JVM of course. Scala is pretty great. I’ll throw my hat in the ring for C# on .NET Core. Just need the dotnet binary to init, build, install, restore, run. It’s like if node included npm in the same binary.
But nowadays it's pretty much installed everywhere? If not installed yet - it's a really easy and quite unobtrusive to install, one-liners in many OSes.
So in the strict practical sense, is that such a big difference? What, extra 300MB for storing JVM? Who cares with 2TB commodity harddrives? (unless you're embedded, but then you wouldn't use Java or Go usually).
As far as I know this is only true for code written in Go. As soon as you try using C libraries you're going to have a non-trivial time statically linking everything. Isn't that the case?
One could equally remember that Java was a niche language in 2000 used by a few dot-com startups, and even today it has not replaced C++, COBOL, or Fortran.
Languages don’t get replaced, people just don’t use them as often for new projects.
> One could equally remember that Java was a niche language in 2000 used by a few dot-com startups, and even today it has not replaced C++, COBOL, or Fortran.
Ouch, the lack of historical accuracy of your comment is painful. Just a few points :
- Sun Microsystem was founded in 1982, it's far from being a dot-com start-up.
- Java was already ubiquitous by 2000, it was embedded in your phones, your credit cards, in your browsers thanks to applets etc.
- in fact it did replace COBOL or C++ for a wide number of applications, not everywhere but it still had a enormous impact on the industry. Netscape even went as far as re-implementing their whole browser in Java[1]. It was a bad idea, but that gives you an idea of the revolutionary impact Java had.
Go is nowhere near where Java was in 2000, by several orders of magnitude. It's not a criticism of Go, I don't even think we'll ever have a language as popular as Java in that time, because in the 90s there was a massive window of opportunity for a language that was at the same time : safe, portable, and licence-free.
Well the size of industry was much smaller than it is today. Java kind of replaced or used in first place where people would have used C/C++ etc. Same is true for Go as lot of container/devops, cloud etc infrastructure is written in Go which would most likely be in Java.
Among the languages that came in last 10 years Go is most popular with exception of maybe Swift.
So compare to marketing juggernaut Java with billions sunk in by leading enterprise vendors Go is nowhere. But among non corporate driven language Go is definitely on top.
> Among the languages that came in last 10 years Go is most popular with exception of maybe Swift.
Go is indeed one of the most popular of the last 10 years, but I don't think it's the most popular one. Swift is way ahead (because of the iOS walled garden), and Typescript is probably more popular than Go (or at least in the same ballpark).
> But among non corporate driven language Go is definitely on top.
Go, «non corporate driven», really ? OK it's not «corporate-driven» like Java, but I don't think anyone would be using Go if Google wasn't behind it. I really think the impact of marketing in Go's success is bigger than its value-proposition (I'm not saying that Go doesn't have a value-proposition, I'm just arguing that marketing played a really big role in its adoption). Consider for instance the microscopic mindshare that Pony[1] has, despite being «Go from the 21th century» with a sound type system and a data-race-free concurrency model.
Marketing aside, people evaluate languages for their community. The lack of a community is something that can be fixed by marketing, but marketing isn't necessary to create it.
Pony is also pre-1.0, and it doesn't look much like Go to me.
Ouch, I should have explained that I was being sarcastic. Javagator was canceled in July 1998, so by 2000 it was thoroughly dead. Sun using Java no more makes it a major language than Google using Go does.
What I remember from the time was that C and C++ was everywhere, and Java was this weird new thing with a bunch of promises that ran slowly (because the JIT wasn't standard until later). There were a lot of people who were dismissive of Java, which was stupid, and there are a lot of people today who are dismissive of Go, which doesn't make sense to me either.
I don't know why the author bothered to even respond to that Medium article. The Medium article starts with that Go shines as a systems programming language. He lost me right there: how can a language with a garbage collector and a runtime be called a "systems programming language"?
"systems programming language" doesn't start and stop with bit twiddling one step removed from assembler.
There's a huge fuzzy region between that extreme and "application programming as a semi-skilled trade", and go seems to fill certain "systems programming" needs adequately as far as that goes.
Languages like C and Rust are true system programming languages, and they are not one step removed from assembler. Rust has a very complex compiler. Go is a low level applications programming language.
This pedantic terminology fight about what constitutes a “systems” language hasn’t been worth having since 2009, when all of these arguments were already aired and resolved. Please find another hill to die on.
He is correct though, at least from the perspective of Go's own designers? Wasn't "systems language" removed from the description at some point. I've listened to interviews with Rob Pike who even outright said they got the messaging wrong there.
I think it's pretty well accepted that no systems language has GC. Go is on the same abstraction layer as Java/C#. Everything in text can be taken as a slight, and to ensure that doesn't read that way, I am a believer in targeting that level of abstraction most of the time. I think it's the sweet spot. I'm not a fan of the dual language approach targeting high (Python) and low (C). Java or C# makes more sense to me, for most software. That's my opinion. If I needed more than what those heavy hitters provide, I'd just go all the way and reach for Rust myself.
So I don't necessary see the parent comment from ctf as combative. I think he's just seeking accuracy.
Java has been used as the implementation language for games, high performance servers, message queuing systems, operating systems, and operating embedded devices for goodness sake. It doesn't get much more "systems-y" than that. Go is surely at least as suitable for these uses.
I think the other commenter is correct: it seems like a semantics argument, and a rather pointless one at that.
You cannot really write an operating system without manual memory management. That's why Go is not a systems programming language. It does not diminish Go advantages: I would personally prefer it as an application programming language to Java.
I can't speak for the parent but he did say "cannot really". I would assume due to that he's aware you can write a research project in it. At one point, I thought Windows was to move to .Net even and MS backed out in the end.
Back to Go, for anyone else reading this thread and wondering what Rob Pike thinks it is, evidence of them removing "systems programming" off their website is here. He explicitly states that he regrets it and that Go is not an OS writing language[0]. Andrei Alexandrescu offers a litmus test shortly after with a property of a systems programming language that Go also fails. If the creator of a language says it's not a systems programming language, I'm not sure how it can be argued by outsiders that it is.
If there's more damning evidence that Go is not a systems programming language, I couldn't imagine what that would be. A shortlist of systems programming languages that would pass any litmus test would include C, C++, D and Rust.
> I thought Windows was to move to .Net even and MS backed out in the end.
If you bother to read Joe Duffy's postmortems, and talks he has made about Midori, you will get it had nothing to do with technical issues, rather internal political wars at Microsoft.
Also Microsoft did not fully backed out, the outcome of Singularity became the MDIL compiler for .NET on Windows 8.x.
Midori influenced async/await, TPL, .NET Native used in UWP and the new low level language features on C# 7.x.
> If the creator of a language says it's not a systems programming language, I'm not sure how it can be argued by outsiders that it is.
I don't have Go in much high regard, but it certainly can be used for systems programming, and is being used as such today, regardless of what the anti-GC systems language crowd thinks.
In that case it sounds like you have a bone to pick with Rob Pike over Go. I suppose you can find him on Twitter if you want to settle your feud. I'd suggest to not bother when I have him on tape contradicting you.
I did read Joe's blog, years ago. Your takeaway there also leaves you with a bone to pick with Microsoft, if it's just politics then you should be able to find someone in management at Microsoft to set straight. It'd be a real shame if there were no performance issues and it was shutdown due to politics alone.
It doesn't matter what Rob Pike says regarding Go and systems programming, because Google, the company that employs him, has decided Go makes sense to write system components of Fucshia in Go.
That is a fact, easily validated in Fuchsia's repository.
According to you, Rob Pike should call management and let them know it is not a good idea to use Go for writing Fuchsia's TCP/IP stack.
You only read Joe's blog years ago, yet you missed the talks he gave.
"My biggest regret is that we didn’t OSS it from the start, where the meritocracy of the Internet could judge its pieces appropriately. As with all big corporations, decisions around the destiny of Midori’s core technology weren’t entirely technology-driven, and sadly, not even entirely business-driven. But therein lies some important lessons too."
"Over the course of 8 years, we were able to significantly narrow the gap between our version of C# and classical C/C++ systems, to the point where basic code quality, in both size of speed dimensions, was seldom the deciding factor when comparing Midori’s performance to existing workloads. In fact, something counter-intuitive happened. The ability to co-design the language, runtime, frameworks, operating system, and the compiler – making tradeoffs in one area to gain advantages in other areas – gave the compiler far more symbolic information than it ever had before about the program’s semantics and, so, I dare say, was able to exceed C and C++ performance in a non-trivial number of situations."
A TCP/IP stack isn't a stringent litmus test for a systems PL. So you can loosen your own standard for what comprises a systems PL, but Go fails more rigorous standards. Everytime. Even Rob Pike says you're wrong and he's certainly a sympathetic character towards Go.
All of this was hashed out years ago upon Go's release, and the Go team took down the "systems language" moniker. That was the end of it. Google knows it's not going to fulfill stringent litmus tests for a systems-language. We'll review the subject again if the folks at Google are brazen enough to ever add it back to the website.
Now Rob doesn't have to call management and let them know it's not for systems programming, Rob & Google already know it's not. He said so himself. You're the only one in the dark on that front at this point.
Rob never said Go wasn’t a systems programming language. He said the pedantic rules lawyering that plagued the internet after the initial claim was made — the tedious pablum that you’re continuing to propagate — was all noise and no signal, and made the claim not worth claiming anymore. For fuck’s sake, give it a rest.
>Rob never said Go wasn’t a systems programming language.
Yes he did. He said it's a cloud-infrastructure language[0] and that he regrets calling it a systems language. That's why he took systems language off the Golang site.
>For fuck’s sake, give it a rest.
Why would we when we're right? Why don't you give it a rest, you've long been proven wrong.
You know, usage of the English language and the terms within matters. Claiming you have a systems language when you don't introduces confusion. You can loosen the terms all you want to but it will never change the fact that GC languages can never meet the strictest measure of a systems language. That's why it matters. No one should be apologizing to you because you don't like the facts.
Unlike yourself I don't care what Rob says, because at the end of the day what matters is what people on the street are using Go for.
Developers don't have to ask him permission or blessing for whatever they are trying to do with Go.
Google is using Go in system components in Fucshia, and the new GPU debugger for Android is also written in Go.
You are in the one in the dark about using GC enabled systems programming languages. I have real life experience using them and have seen it works.
I lost interest on Go due to its spartan design, but certainly will encourage anyone trying to use it to build an OS from scratch, regardless of what is written in a web site.
"They did not know it was impossible so they did it"
The reason Rob's statements matter is because he's the authority on Go. If you had been a primary inventor of a new language, I'm guaranteeing you'd feel entitled to decide what it is and is not. Not have "pjmlp" debate endlessly over something you had already stated was simply not true.
A lot of things work, doesn't mean they meet strict litmus tests (which matter, because definitions matter), nor does it mean it's a good idea.
When a language is set loose to the world it belongs to its users, and whatever they decide to do with it.
Anyone is free to just fork Go and do whatever they feel like with it, regardless of what Rob thinks. That is the beauty of MIT license.
So given that Oberon is accepted as a systems programming language in computer science, with multiple published papers and books across two decades, heavily used in OS research at a couple of European universities during the 90's and an influence to Go, with hardware and compilers still being sold for systems programming, although in small scale.
What are the actual technical features Go is lacking that makes it impossible to be used for systems programming, given Oberon's influence on its design?
Your concerns have already been answered. Most succinctly stated by two points.
1) A lot of things work, it doesn't make them good ideas.
2) Go doesn't meet the strictest litmus tests of a systems language, never did, never will. It's only a systems PL only if you relax your definition of what it is. Go's own creator says it's not and if any one person is the authority on this topic it's him. There are platforms that meet all definitions, those are definitely systems PLs.
It doesn't matter what people like yourself think or attempt with a given technology. This is about technological definitions. Go is not a systems PL by the strictest measures available, that's a fact. Designers of C++, Rust, D and Go for the most part agree on that. You're the only odd man out. Redefining terms or loosening the standards for quality is an intellectually deficient venture. Some may partake in that, myself and others refuse to. It's best to leave it at that, it boils down to intellectual honesty vs dishonesty to push your viewpoint.
Rust’s designers aren’t really interested in playing the “what is a systems language” game, honestly. We are even considering abandoning the term entirely when describing Rust, as we’re not sure it’s a particularly useful term.
A strong litmus test as the one given by Andrei (creator of D for those not paying attention), settles the definition well enough. I'll even back off that claim because some absolutely refuse to accept a litmus test to meet definitions of things, as they're so hellbent on not being excluded. Unfortunately that's how language and the world works, not everyone gets their way.
So we'll just settle on once there's a commercially successful operating system built in a GC'd language then I'll eat crow but till then they're all going to be C/C++/D/Rust or built on similar abstraction layers. Go ahead, wash away Linux, iOS and Windows in the competitive landscape with something written in Go. Let's see it, that's believing after all. It'll never happen because it's unsuited and inferior for that purpose.
I think you are confusing the language runtime with the Go "runtime" package that provides an API to the Go runtime. Golang runtime is basically a program, that is running whenever your Go application is running. As a programmer, you do not have full control over the language runtime. It runs things like garbage collection, and serializes/deserializes data in the channels. True system languages like C do not have a runtime. Rust has a primitive automatic memory allocator/deallocator (not a garbage collector!), but I would not call it a full fledged runtime.
By that definition every language has a runtime (yes, including C with crt0.o). Something has to set up the stack, enter the main() function etc. So how do you differentiate a systems language runtime? One that is bundled with the OS? Or is thin enough by some arbitrary measure?
In Go you cannot fully control the runtime as a programmer- Go's GC is a complicated periodically run program with sometimes surprising behavior.
crt0.o is a very simple set of startup routines with a fixed and predictable behavior. It is typically run only once ("0" in the name is for startup), and has only a couple of assembly instructions.
C runtime does much more than that, depending how floating point is supported, language extensions for constructors on execution start, threading runtime introduced in C11.
Colloquially, this. There's historically been a fairly big gap between "very little runtime" and "more runtime", so "no runtime" and "runtime" are what people say.
That said, the word is generally ill-defined; some people use it to mean "interpreter" or "vm" rather than the classic definition, which is (as you say) that every non-assembly language has a runtime.
OK, if you really want to go as far low-level as possible: My mother, back in the 1950s, worked on at least one CPU where the instruction set could be changed with patch cords. So is the configuration of patch cords a "runtime"?
I guess not, but uploading a micro-coded bytecode interpreter into an Alto CPU in 1973, to switch between Smalltalk, Interlisp-D and Mesa/Cedar support certainly feels like a runtime.
very interesting. I would have thought that any practical kernel written in a language with a GC would either have unpredictable slowdowns or be exceedingly complex.
We already sacrifice some silicon for TLBs and other memory management features. Many older architectures sacrificed bits for tag information as well. Perhaps one day we will sacrifice a little more silicon to get performant hardware-assisted GC?
I don't think that is a necessity. You can write Go code which doesn't heap-allocate at all - the Go GC is written this way in Go. In any case, you would have very little heap allocations in the kernel space and the GC should be well integrated with the kernel operations.
> At ETHZ Oberon workstations were used during a couple of years by several users across the department.
The way you say that, it sounds pretty unimpressive. Say, 2 years and 10 users, plus or minus one order of magnitude. That's not enough to tell anything. Was it going to be portable to other hardware? Was it going to be maintainable? Was it going to be comparable in performance? The answers are all "no data". The only thing you can say is that it could be successfully written and gotten to work, for a definition of "work" that allowed a few people to use it for a little while.
> Most of those attempts failed due to losing the political and financial wars of bringing them into the wider market, not because of lack of features.
Well... I wasn't there, but I took a look at the Wikipedia page (yeah, I know) giving the chronology of the Oberon OS, and it's quite unimpressive. For four years, it had "only simple text editing facilities". Those four years ended in 1991. That sounds very much like "lack of features" to me.
In particular, the competition was either DOS, Mac, or a Unix workstation. That feature set would not lead anyone to want to choose Oberon.
Now, I know, there were only a couple of people working on it part time. But all this really proves is that they were able to write an OS and get a text editor running on it. That's proof of concept, I suppose, but there's a huge difference between an OS like that and an OS you can "bring into the wider market".
I think you're idolizing a past that wasn't all that hot at the time...
Native Oberon was the very first version, then there was EthOS, and Oberon System 3 with the graphical Gadgets framework.
In the meantime a new version of Oberon was re-done with Oberon-2, whose method declarations influenced how Go method declarations are done.
By this time there was a spin into a Swiss startup that designed Component Pascal, an Oberon-2 derivative, with a RAD development environment targeted mostly at Mac OS and Windows users.
The researchers at ETHZ created Blue Bottle OS, also known as A2, using Active Oberon. Yet another Oberon evolution, that had support for co-routines in async/await style, and probably one of the first environments with a multi-threaded compiler.
It was good enough to support applications like video playing, BeOS wasn't the only one doing it in the mid-90's.
If you want pictures, there are plenty of them here,
Graz University had their own variant of Oberon, with Hanspeter Mössenböck leading some of the development efforts. This same department is nowadays heavily involved with Graal research together with Oracle Labs.
It did come across as quite patronizing. Particularly in contrast to its light-weight argument style that almost exclusively consists of one-sentence opinions, stated as fact, with very little behind them.
PHP is unique in several ways: it's especially designed for the web, is a Web framework itself, comes with everything inbuilt, has C/Java syntax, has a shared nothing architecture, replaced VB as the most popular language for beginners, is used by most websites, is easy to use just drop a php file to Apache www dir. You simply can't objectively compare PHP to other languages because it's different to all others, it's unique. And due it's wide spread usage and earlier non-academic approach it still gets (rather unfairly) some bad reputation. Anyway PHP 7.2 is great, and Go too.
But a pokemon character was rather unkind to it back in 2012, so here you are.
Two years after that, Mickens wrote a glorious takedown[0] of Javascript--which must not have been as glorious as I thought--since people still seem hell-bent on using in as many places as possible.
Alan Kay said that computing is now a pop culture...
I mean, the way people bash PHP and praise javascript is completely ridiculous.
The two languages are comparable at best in the amount of warts they have, while my firm opinion is that the js ecosystem is the most horrible thing in the world.
Go is not OOP in any shape or form, no matter what “they”
try to tell you. Go is imperative language with procedural
style of writing code. Yes, you have objects and you can
attach methods to them, similarly to Ruby where everything
is an object, but that’s basically it. Never, ever, try to
repeat yourself in Go. You will crash and burn.
When it comes to Go, spaghetti code is what you want to write.
This was really funny. Definitely the rantings of someone who is used to too many layers of abstraction and coded themselves into a corner before finally blaming the language. I'm detecting a lack of self-awareness. Here is where the author should have used the gif that was used at the start of the article
> thank you for designing your website so that can actually handle some traffic. That's worthy of the hacker news gold achievement
Not really. When I had a blogpost on the frontpage for the first time, I checked the monitoring and saw a CPU load of 6% of a single core and 1 megabit per second (that's bit, not byte). [1]
And it's simple, really. You just write some text on the page, add a small stylesheet. And then you just stop, resisting the urge to add any JS and tracking and hero images. You just stop. And instead of generating your HTML on the fly from a database, you just serve a static HTML file.
It is a fair enough point though. Even Go written by pros often does not fit together easily. Adjusting one library to fit with another is often a non-trivial task, and many package authors freely admit as much.
I must have links to at least five different gzip middlewares in my favorites, and I'm sure there are more than that...
At which point is it easier to put the app behind an nginx reverse proxy? Chances are that you have a reverse proxy anyway since one Go app is not nearly enough to saturate a server CPU.
Point being that something which could be easily slipped-in with a more dynamic language triggers a total re-wrap in Go, or punting to an outside system like your example.
Not hating on it though. I like Go for network-y things.
edit: And in your example, is it a clear win to centralize compression at the proxy?
If I had to point at one thing Go did exactly right, I'd choose the "OOP" bit. Inheritance is an anti-pattern. Interfaces is the way to go.
Maybe the only thing I'd add is a compiler warning when an object which does not declare itself as interface X but complies to it is used as interface X. (Typeclasses would be even better, but it opens the can of worms which is the support of generics.)
From My point of view. Go is a great language and this author is right when talking about using Go is better than PHP in cases like Uber or Youtube. I mean, Im not a fan of PHP, I like to use low level languages the most time but web is complicated. First of all, I don't think that not abstracting all the IO and network HTTP socketing or all this stuff 'helps' somehow developing a 'better' web app. Maybe for Uber, Youtube, Google, Docker, AWS, yeah. But for the most of everyday-apps for small/mid-sized business? I don't think so. I mean, it would be great but from my point of view, developing a Go web app for this kind of business, but it could be a little bit overenginered. Using PHP/JSP would be much more straightforward for the developer/s, and maybe for maintenance. The entire cost of the app will be greather as Go developers for Web Apps cost you more than any PHP/JSP programmer out there. Remember Ruby? It's the same problem. From the point of view of engineering, right, take Go, but I think sometimes, isn't necessary. PHP is not the solution but will solve you some problems that could be great for even mid sized businesses. Just my opinion.
I think JSP is a great contender, and I see your point about overengineering. PHP with type-checking is alright, but if I'm going to use a scripting language I'd prefer Python or Ruby.
Both ruby and python seem to encourage duck-typing. I worked with both of them in the past and that's the main reason why I always came back to PHP. I need my type declarations...
Agreed. The way i see it for the web is PHP is just a better Ruby/Python in terms of libraries, package management, deployment, language features, performance, with the only drawback being a quirky standard library.
All of the points this article makes are already addressed in the last one.
Yes, Uber is running a production Go service with massive QPS. This is exactly what the original author meant when referring to Go's strengths with single-purpose, high performance, "nano" services with relatively little business logic.
There is also the insistence that frameworks are bad and developers absolutely have to care about "granular control" and "manipulation of bytes and bits" and packets and IO (unless they're writing a "glorified todo list") which rubs me the wrong way. Why is it so hard to acknowledge that there are a large number of perfectly good websites and codebases that do well with popular frameworks?
We ourselves have a proxy layer and a couple other services written in Go, and they work great, but the rest of our stack is Java and some Python. Developers are free to choose the best tool for the job when starting new project, but after a few days of messing around in Go every new service is undoubtedly built using our existing web stack.
I don't know Go and I didn't use PHP very much so I'm qualified to comment only on this part:
> I’ve worked with RoR, and a variety of frameworks in the Node world – and I have never had a framework project where I didn’t end up fighting the very system that was supposed to make development “easy”.
This is not my experience with Rails, Django and Phoenix. Actually, I was probably fighting Rails in my very first project in 2006 (or was it 2005?) but I was writing it as if it were Struts (I was coming from Java.) Then I started coding as if it was Rails and got a great speedup in terms of coding time. I'm less proficient in Django. It seems that it doesn't really enforce a project structure and one can do almost what s/he wants. I've seen projects that look very different to a degree I never saw with Rails. Basically all Rails projects look the same. Phoenix is somewhat in the middle.
So, if the author is wrestling with frameworks either he's not proficient with them, but this doesn't seem to be the case, or he genuinely doesn't like to be constrained by the requirements of those frameworks. This is not a bad thing per se. If one feels like that, he's going to be a happier developer writing code with the architecture he designs. I'm not sure customers will be happy too, but I don't know what kind of projects and customers he has.
About me, I prefer to stick with standardized architectures that any developer after me will be able to understand in minutes. I'm a freelancer and I just don't have the time to spend a significant amount of my customers budget to learn (and make learn) more clever and optimized architectures before doing any real work. If I had my company running around one software product, then maybe I would design it from scratch. Reality check: I wrote so many MVPs in Rails, especially for customers. Given the usual outcome (failure to get traction) it would have been a waste of money to start with a more clever design.
For example, the labstack echo framework in Go is one of my favorite frameworks, it does a lot of work for me. On the downside, I can't hijack HTTP connections in the router, like for example, when I want to host something under customs domains and redirect internally to a subURL. I have to hack around the framework to do that, the solution is rather ugly. But there isn't much I can do otherwise that doesn't have various amounts of bugs.
Frameworks will always limit what you can do, period, you will have to code around them once you want to do something they don't allow out of the box.
On the other hand, the less the framework does for you, the less limiting it is but in the same moment it also does less work for you.
> For example, the labstack echo framework in Go is one of my favorite frameworks, it does a lot of work for me. On the downside, I can't hijack HTTP connections in the router,
This isn't a problem with "frameworks" but a problem with the library you specifically chose which is bad since it doesn't even fulfill your needs apparently. I wrote my own go http router, and I have no problem hijacking the connection and filter according to hosts, at all.
Writing a custom http router is kinda contra to the point of using a library, no?
I don't want to bother with writing my own router and this was one of the few times I had problems.
I think even if I wrote my own framework, I would eventually end up having to hack around it anyway when I inevitably need to do something the framework I wrote just fundamentally can't and I suggest this will be the case for your custom implementation too.
So don't evolve your project based on HTTP stack more than an HTTP stack may allow you to.
Suddenly, you'd like to have real-time comm? Don't add WebSockets, simply because they fit right above the whole of your stack based on HTTP. Use TCP.
There's a very gentle balance between using what you've already got and introducing a set of newer entities into the system; and sadly this is not always that clear, which one you should use.
Yes and that's quite obvious. However, frameworks are stil a limiting fact in code. If I use a framework it won't let me do certain things. Which means I have to hack around or introduce newer entities/dependencies.
A balance must be found, in one of the earlier examples, a quick hack was easier.
From my point of view PHP 7.2 is a great choice for startups and with a small team, so build the product, make it run. If required then do some R&D to switch to go, jumping straight into go should cause some issue.
Good luck hiring actual software engineers and not the ones who just managed to get into IT during the SEO boom. They are probably less expensive than the Py ones, but they probably don't have much of a future either.
Still parroting that old trope, huh? The quality of an engineer is rarely dictated by their tools. You can be an excellent engineer with a shitty language, or you can be a terrible engineer with a great language.
I'll be the first to admit that PHP certainly has it's share of really bad developers, but what language doesn't?
It is an old trope - I completely understand your point, but the fact is: wherever you're professionally going, PHP is <probably> not the language you'd like to use anyway. So why use it?
I could see how doing FORTRAN for a banking institution is a good way to make money; but PHP doesn't even have that.
Most of my closer friends with a Computer Science degree would probably try to stay away from PHP: neither does it pay better than other languages, and most of the companies that have chosen to work with PHP <probably> don't seem to be that appealing either.
Is that an old trope? Well, I am parroting the industry: I had worked with PHP and I had realised that none of the cool people with money would do PHP anymore. It literally is similar to not using git in 2017 - if you're still doing PHP, then you're probably a dying business or a really bad software house.
> wherever you're professionally going, PHP is <probably> not the language you'd like to use anyway. So why use it?
Unless you're doing web development. Outside of the HN bubble, there's still a very active segment of the software industry that uses PHP. Yeah, it's not a "cool" language or whatever, but experienced PHP developers can churn out solid work very quickly.
I made pretty good money as a PHP developer for a lot of years - you would not believe the places that this language gets used (and in what ways). "Dying business" is definitely not how I'd describe my past employers.
I have been writing Go, Node.js and PHP for quite a while now. I don't think golang is overhyped; nor it's a silver bullet. There are systems like Kubernetes, etcd, and so on that are implemented in Golang and they work really well. I think problem is people trying to use Golang for EVERYTHING! There are so many things I would disagree with in the article; but I won't disagree with the fact that if you want language with dynamic nature (Ruby, PHP, JS) and you expect to find those conveniences in Golang you are flat out wrong. Reading original article this is the exact feeling I get, somebody was like "look look a cool new toy" and the herd followed.
Many people were taught OOP the UML and Java way†, to which the concept of prototype-based inheritance is completely alien, while composition is not even on their radar.
† Although they have their fair share of issues, this is not a jab at UML nor Java themselves, but the way things have been taught, terribly, for so many.
Yes that's true. When I was at university we learned about the concept of composition but the reference language for this 'software engineering' course was C++. The whole composition idea felt contrived at that point.
Some time later I learned Lua for fun and almost instantly understood what this whole prototype based programming / composition was about :)
TLDR:
While I learned about composition at university, they failed to really show how it is used and what it is good for..
JS mixin / Ruby module / C++ mixin style composition are less than excellent, mind - throwing all the methods from multiple locations into a single scope is a recipe for implicit dependencies. There's an assumption that you won't define any methods that the mixins also define, not only today, but in the future; and even more, you assume that a same-named method won't be defined in multiple mixins, not only today, but in the future.
IMO it's much better to explicitly reference all mixins, and compose by reference rather than by direct inclusion, unless the composition has strong reliance on the identity of 'this' / 'self' in its implementation.
While Lisp is usually associated with FP practices, the CLOS (Common Lisp Object System) really helped me with getting OOP to click as a concept. Part of it is that, CLOS is just Lisp, so all of the concepts of OO programming are there with none of the syntax generally added in other OO languages. Also, the method/function names clearly name all the concepts instead of using opaque notation: SLOT-VALUE instead of dot, arrow, or double-colon notation, DEFCLASS does what it says on the tin instead of the vaguer "class ClassName { }" of C++/Java/etc. I feel like this makes it clearer what is happening. A good overview of CLOS is chapters 16 and 17 of /Practical Common Lisp/ (http://www.gigamonkeys.com/book/)
I've heard other people speak similarly of learning Perl's MOOSE after already being familiar with non-OO Perl. This probably is no coincidence since MOOSE is heavily inspired by CLOS.
I'm being very serious here, with no sarcasm: Using a language that has an alternate model of OO that either simply doesn't have inheritance, or makes it relatively hard.
IMHO it doesn't matter much how much you read about the differences, until you get in there it won't do much good. This is a good place to have a throwaway project on hand, because your first try is likely to be a very big mess.
If you know an inheritance model and a non-inheritance model, you'll be well on your way to understanding the nuances because you'll have the experience in the field.
(For reference, my personal definition of OO is pretty much any language where you can write object.method(arguments), some kind of polymorphism is made available on that, and that is either the primary or a very important element of design in the language. It's a very expansive definition because I find that having massive definition debates about what OO is to be nothing more than useless flamewars.)
> You are only happy if you look for a better C which most people aren't.
I'd argue Rust is the "better" C. Go is a "simpler" C, at the expense of expressiveness, features, speed (only noticable in very low level usecases) and applicability for certain domains (Go is primarily for networked apps).
In the same way Java wanted to be a simpler C++ (which came with it's own drawbacks).
And for me Go is more of a competitor to Java (as Java is mostly used for networked applications) than it is to C.
Rust loves zero cost abstractions, and isn't afraid to be complicated. It gives the programmer as much power as possible.
Go is simple and actually very fast. The garbage collector is probably the biggest hurdle for performance and it's still best in class. Definitely higher level than C, but not enormously so.
C sure is not afraid to be complicated. But at the time it was huge simplification. I'd say Rust's complexity is not there for it's own merit, but has huge advantages (though not that visible in a very small project).
> It gives the programmer as much power as possible.
C++ has static dispatch classes, templates, constexpr, and macros. C just has macros. Any other abstraction costs machine code. C++ also offers a lot of low cost abstraction like RAII-style scoping.
>C sure is not afraid to be complicated.
Not sure in what sense you're talking. C is not complicated. It's low level. It's exposing complications in the underlying model of a computer. Example: pointers in C are not complicated. Understanding how they work may be for beginners, but that just reflects how hard it is to understand what's going on in a computer.
C is accidentally complicated where it is flawed; the non-orthogonal behavior with arrays and the syntax for function pointers are examples. Go fixes some of these flaws, which is unsurprising since it was informed by people close to the origins of UNIX and C (y'know, like, Rob Pike?)
>I'd say Rust's complexity is not there for it's own merit, but has huge advantages (though not that visible in a very small project).
Sounds a lot like C++. It isn't accidental or coincidental that it is a favorite for high performance but complicated stuff like game and browser development. This is no surprise since Mozilla wrote it to replace usages of C++ for memory safety and concurrency, not because C++ didn't offer enough. C++ is flawed in ways Rust isnt, but that doesn't mean the two don't share a lot of traits, and it was Not by accident. Complexity is one of them.
>C, C++, Rust are all in that corner.
>
>Go obviously isn't.
Since you've offered no reasons for why this would be true, I can't actually refute it. But it doesn't make a ton of sense. Go and Rust both let you shoot yourself in the foot literally as much as you want. Go directly facilitates assembly code and allows direct memory access with unsafe. Rust also does this. Go tries to be memory safe and provide concurrency primitives. Rust goes about this in a different way. I don't see where they significantly differ.
Rust differs most in it's superior memory safety model and low cost abstractions. Go differs most in it's simplicity and built-in concurrency. But they both feel close to their own origins.
Yeah, that is actually a pretty good point to be honest. Go is not ideal for low-level components such as that. I suppose the analogy of Go and Rust being successors to C and C++ is reasonably flawed, from that perspective.
On the other hand, I'm glad things are turning out the way they are. Rust and Go are both filling niches that C and C++ didn't, in ways that they couldn't have. I look forward to Rust-based OS kernels, for sure. It seems like with time, we can build very resilient foundations with Rust that wouldn't have been possible before.
You can use atomics and syscalls and even assembly in Go to have complete control over the system in the same way that you can in C/C++. It's definitely not trivial to bypass Go's memory model and get raw access to memory, but you can do it if you want. I'd say that Go discourages you from doing so, just the way Rust discourages the use of unsafe memory access even though you can if you want.
Go strongly pushes a "way to do it", see concurrency for instance. C/C++/Rust have a (one or more) paradigm, but they leave as much liberty to you as a programmer as possible.
This I see as a stark difference.
Wrt concurrency, Go is more like Node: one way to do it.
Seriously? That's news to me. Only C zero cost abstractions I know of are based on external code generators. Or some macro abuse, but that's rather limited way to create abstractions.
But then again, when you really need to understand everything that is going on, abstractions are often not helping you.
(I write kernel drivers and bare bones embedded, where memory measured in kilobytes, not megabytes.)
> These are hard issues to solve with PHP, so hard that Facebook hand crafted a SPECIALIZED VIRTUAL FREAKIN’ MACHINE to deal with the performance issues inherent in PHP. Does that really seem like an “easy” solution?
It is worth noting that this was pre-PHP7. Post-PHP7 the out of the box performance is similar or better to what Facebook did with the HHVM.
Also, very few projects will ever end up at the scale (user base/metrics) that Facebook had.
99% of all PHP software will be fine with a quadcore server with 4GB RAM, running a LAMP stack. This can be scaled as needed (eg moving off mysql, adding a reverse proxy, real load balancing).
I've always been really skeptical of those language performance comparisons which refer to PHP.
As stated above PHP7 has similar performance when compared to HHVM which was made by Facebook. Additionally PHP has an amazing performance debugger by FB called xhprof.
PHP performance could always be increased hugely by making sure is cache buckets have enough memory (opcode cache, realpath_cache_size).
Secondly with any web framework your app will most likely be limited by IO (database, file lookups, networking) before it becomes limited by actual code execution performance.
If anyone's ever worked on a project where the performance problem was the language and not IO I'd be really interested in hearing about it, but in my career of making websites I've never ran into this problem yet.
Being skeptical is a good attitude. I'm very skeptical of this Eldorado that some posters see in PHP7. My experience is quite different.
> Additionally PHP has an amazing performance debugger by FB called xhprof.
xhprof is unmaintained for years. The official version does not compile with PHP7. Various forks exist, but the only stable fork has been rebranded and defaults to sending all the performance data to the branding company.
> PHP performance could always be increased hugely by making sure is cache buckets have enough memory (opcode cache, realpath_cache_size).
Always, really? The history of PHP opcode's caches is complex. Before PHP5.6 where Zend published their opcache+, I've seen the various solutions (APC and others) cause vicious bugs.
> Secondly with any web framework your app will most likely be limited by IO (database, file lookups, networking) before it becomes limited by actual code execution performance.
I've seen quite a few PHP applications that were CPU-bound, and that were far from Facebook's scale. For instance, the learning platform Moodle is popular with universities, but getting it to handle hundreds of concurrent users cannot be done on a plain quad-core server.
Another poster suggested load balancing as an obvious solution, but adding this is not that easy. E.g. Moodle has to track various files, including uploads. So once you add a load balancer and several PHP servers, you need to use a network mount for most of your files, which has a big impact on IO performance.
I'm not saying that other languages are better, because I can't compare the exact same large application in two languages, but PHP7 isn't an Eldorado.
> So once you add a load balancer and several PHP servers, you need to use a network mount for most of your files, which has a big impact on IO performance.
That depends if you set up cachefilesd correctly. Many people think it's enough to do the NFS mount and that's it, but it's not - NFS's mount parameters have a big impact on performance, and having cachefilesd enabled can make performance go through the roof, especially with big files. Without cachefilesd the only caching is in-kernel memory, which can and will lead to files being evicted from the kernel cache...
Same for MySQL - having configured it correctly (or incorrectly!) can make a life-or-server-death difference.
All without having to touch PHPs configuration... there's a reason why a good operations guy is worth his weight in gold.
Hmm. I don't trust any external CDN, to be honest. No matter which one you choose, you lock yourself dead into the vendor - should it decide to kick you off for whatever reason you're toast, but especially I'm afraid of doing a tiny mistake in AWS leading to accidental disclosure of private data.
Such "hacks" have hit too many too big firms for me.
Out of interest, what issues have you had with NFS mounts? I run a fleet of virtual servers with their disks on an NFS-mounted NAS share and backed by cachefilesd, never had a problem with that setup.
Eventually, NFS ends up freaking out and consumes all I/O on the client machine until it is rebooted. I suspect that this occurs when the underlying network is saturated, but don't have evidence of such. CentOS 6/7, NFS v3/v4, tuned every setting I could think of, and spent dozens of hours Googling and reading.
It may be worth mentioning that we had decent throughput with NFS. Roughly 10 writes per second (from 100kb-250mb) and 20 reads per second (IIRC).
We use rclone to do a daily backup from primary -> secondary cloud file store, and use a little wrapper function in app to switch which host we're pulling files from so it's not too hard to failover during an outage.
I do agree with you about vendor lock-in though, it's nasty stuff. At the end of the day it comes down to time allocation. I'm a one-man ops show with too many other things to do than to wake up with a Pingdom alarm at 3AM because of NFS.
Whoa. I have never hit this one, to be honest, in years. Maybe it was something CentOS specific, I have everything I have control of at either Debian or Ubuntu... but I will keep this in mind in case I ever do hit this error.
Might have been worth a try to get a RHEL support contract, but if you're a one-man show and happy with CDN, then that's the better solution for you definitely ;)
> Always, really? The history of PHP opcode's caches is complex. Before PHP5.6 where Zend published their opcache+, I've seen the various solutions (APC and others) cause vicious bugs.
First of all realpath_cache_size is unrelated to opcache and has always worked well. The only problem with that configuration is that the default is waay too low for modern frameworks.
Also I think GP meant that now you can always finetune the opcode cache. The current opcache is built into php 5.5+ and just works. It works so well that there are almost no competitors because there is no need.
We are working on separating the extension that powers our SaaS APM for PHP and the original xhprof callgraph profiler again into two extensions in the near future :-) Then the extension will still be branded, but it has no code related to sending data to our service and just the backwards compatible profiling API.
Depends on the use case. I've definitely worked with projects that required a ton of capacity, because the realtime search functionality was booting the full Symfony framework every time someone typed in a letter. To get rid of those performance problems, someone builds a fragile mess of PHP. In that case something like Go or Node.js is a much better fit to the problem.
But if you're building a big old MySQL CRUD app full of complicated business rules, PHP makes a lot more sense.
> Secondly with any web framework your app will most likely be limited by IO (database, file lookups, networking) before it becomes limited by actual code execution performance.
Latency is additive; it's a sum() operation, not a max() operation. Yes, a large fraction of most web requests get eaten by blocking on IO, but everything on top of that adds up, and small numbers add up surprisingly quickly. And the more you try to be smart about that stuff, whether it's optimizing what you query, do extra caching, try to turn multiple DB roundtrips into a single trip, you often just trade IO time for CPU time (albeit lower). You still care about CPU performance.
> Latency is additive; it's a sum() operation, not a max() operation.
This! And you can only discard some components latency when it disappears in the deviation of another components much larger latency. In most PHP (or Ruby/Python/etc for that matter), this is not the case. They add some 10-150ms on top, and often the db calls are <10ms.
Performance does matter, and is hard to improve once you have many KLOC of code in a slow language. Hence FB spend big bucks on PHP performance improvements.
Most are <10ms. Those nasty few ones with 100+ms (or sometimes 10+s!) are where the best money is spent optimizing. However good query/db schema optimization is a skill many developers do not possess... which is why a good DBA is worth his weight in gold.
> If anyone's ever worked on a project where the performance problem was the language and not IO I'd be really interested in hearing about it, but in my career of making websites I've never ran into this problem yet.
Our company's product is CPU bound, and our language (Python) is definitely inhibiting our ability to meet basic performance goals. I've done a few crude benchmarks and I'm confident that a rewrite in Go would buy us at least a tenfold performance improvement, although the benchmarks themselves suggest it's closer to 100-200X. Besides being faster out of the box, Go is also easier to optimize--better profiling tooling but also the ability to control memory layout, allocations, and dispatch. And that's all without parallelism.
or alternatively break out the big CPU bound bits into an FFI language, i.e. C, Rust, Etc. That's why Python has these bindings. You can almost sort of do it with Go, but it's not easy, since Go has a VM as well.
Go doesn't have a VM, but it has a garbage collector and scheduler (its runtime) which makes FFI more difficult than languages like Rust or C, to the OP's point.
Unfortunately, the bottleneck is largely traversing a massive, poorly-defined data structure. If you leave the structure in Python, then FFI doesn't help you much (probably doesn't justify the maintainability cost of FFI). Porting the data structure is a comparable amount of work to rewriting from scratch, so FFI doesn't gain us anything except maybe an iterative avenue toward rewriting.
In any case, the application is still CPU bound, thereby making it an example of a web application which is not IO bound, per the OP's request.
Of course there are CPU bound web-app's. That the OP thinks otherwise is just ignorance. But most web apps are not CPU bound, most are IO bound.
You can start with things like Cython which will give you a modest boost over plain python. I agree it may not be useful in your case, but doing full-rewrites are generally awful, abysmal and a nightmare all combined. Sure, there are cases where you must for various reasons, but they should be avoided if possible.
That's the beauty of doing something like an FFI with C/Rust/etc. You can iteratively move that direction, get code deployed faster and get your performance gains, while also slowly moving into a full-rewrite, but it can happen gradually and you get all the perf enhancements during the re-write, plus you get code deployed in production faster, so you can get all the code tested, and make end-users lives much better in the process of your re-write, instead of making them wait until the bitter end and then finding out that X, Y and Z undocumented features customers were using didn't get included in the re-write.
Anyways all that said, it sounds like you know what you are doing for the most part, so my advice here may not apply to you directly at all, and that's certainly plausible. But I think in general it's fairly obvious to experienced devs that re-writes are an awful plan.
I agree--rewrites are painful, and most web apps are not CPU bound. FFI does permit iterative translation, which is a great bonus, although I don't want to end up owning a bunch of C or Cython. Rust appeals to me, but I don't think my peers would agree. Not sure what we will end up doing, ultimately. :/
In cloud time performance is simply a matter of cost saving. No matter what your needs are, if you're able to serve more request per cpu cycle or Mo of memory, then you'll save on server costs.
Not strictly about Go, but how is it supposed to impress that 'big company X' uses language Y (in this case the author uses Uber as if that's some kind of + for Go); I would be far more interested in the language + framework used to solve what level of complexity and scale problem with how many servers + people. If you can build & run something with less people and servers than your competitor and which makes you make more money, I think you have something in terms of framework and language. I think K/Q exists because of that and Janestreet uses Ocaml for that reason.
Also one should not forget that a company with 1000s of engineers is probably not you (yet); when you read that some company runs successfully on Node and saves $n amount of money by using it etc; when they have 1000s of engineers and devops on top of that it doesn't mean you can achieve the same (or any) success with it with 2 people. PHP for instance might be a much better choice with a small team; you don't need complex server setup, you don't need (or can handle) middle of the night alerts that require you to dive in vs just reboot the server etc.
For most setups at most ISPs, PHP servers are zero setup, self contained systems which, without any setup from the client (the user, you), comes back after reboot with no issues. It has also been the case for 15+ years so it's quite something you can actually trust to happen.
This is not so for Go or Node for most hosters out-of-the-box. Sure in the HN echo chamber, every hoster offers this maybe, but there are literally 100000s of small/big hosting companies/resellers in the world that run, say, CPanel. And the only thing that is trivial there is LAMP (with PHP/MySQL) hosting; the rest is just not very convenient or even impossible.
So once you set it up, no there is no difference, but then you have to know how to set it up, secure it, have access to set it up and secure it and know how to maintain it which is the point i'm making (not meant about specific environments besides PHP/MySQL); if you are a small company that needs to make money, you might not(!) want to bother.
Edit: Cpanel, in some near-future version will offer Node, I cannot find Go though.
Edit2: I'm definitely not recommending anything here or saying Cpanel is any good; I just know it well and I know that it's the most installed 'admin panel' on hosting servers.
You'll need the go process to complete all ongoing requests before restarting it. Whether that be RPC, HTTP, WS, etc. And this is behind a load balancer, so did you just go offline, or are you doing this one at a time? With PHP, you don't have to restart php-fpm or modapache. Just git-pull or FTP the new files in and the next HTTP request will automatically user the new version. Zero downtime. Honestly though, I expect something like AWS and GCE to already have our to be building a solution to handle the go scenario efficiently for you.
This would be easily achievable by having 2 processes: one, which accepts the socket connections and relays them to the subprocess which does the actual work. New subprocesses could be started any time for updates, without killing existing connections. All new connections would be handled by the new subprocess.
Right, as Go is compiled into a static executable, you can't do code updates on the fly that easy. A small price to pay in a production environment. On the other side, you do have all compiler checks run while building.
How do you deal with changes to multiple files at the same time? What if a subset of users see updated file A but not file B?
You don't have such things in other languages simply because they have not been initially created as glorified templating engines. More importantly: for example, Django in debugging mode allows you to swap templates on the fly, so is with the executable code. Except nobody does it because that's considered ridiculous.
At my job, before I joined, I was told we were torn between using Go and Rails and ended up with both. Now we have a Rails frontend (for web requests / authentication) and a Go backend (for business logic), which communicate over Thrift RPC.
I don't think it was a very wise decision because not only are you doing things twice, you're doing it three times, because you have to serialize/deserialize to/from Thrift for every request. It adds development time, more tests, and Thrift's binary protocol makes debugging RPC almost impossible.
This isn't really an argument for/against Go, but it just shows that you should try to avoid using multiple codebases that have to be tightly integrated. Personally, I would've gone with a Ruby-only codebase that used Thrift RPC only if there was some backend task that was too slow in Ruby, and that Go's concurrency and speed might be better at. Then I'd serialize it and send it over to be processed by a better language. I wouldn't do it for every request.
That being said, if I had the choice between writing an API in Go vs Rails, I would do it in Rails for the faster iterative development speed and quick debugging capabilities that is made possible by an interpreted language.
Have you tried thcurl or yab for debugging RPC? I’ve found that most services I consume using thrift have a yab template for easy testing and trace ids so I can follow the request- I haven’t really missed hand writing JSON curls yet.
For god's sake - does the structure of this project do any good to the company, or is it just there to familiarise the developers with a variety of technologies so that then they could go to another company and boast having used all of them?
Hard to debug binary-based RPC? You have picked the wrong technology for communication, having forgotten that you'd need to build the necessary tools in order to debug it. There's literally nothing wrong with binary protocols, except developers forgetting about the necessary overhead of re-parsing the passed data in the debugger. But it's not an overly expensive overhead, if the architect had taken this into account.
Having heard this point absolutely not for the first time, the only question that remains is: who and why did make a decision to have it this way?
I see no facts or genuine refutation in this article, just opinions. Therefore I can only assume that truth hurts because the article you are trying to argue with has a bunch of valid points. If you look at the history of Go you have to realize that it was created for the reason which is in the original article: to be a better C.
If you come from C it is good, sure. And you can write big projects in it like in C (just think about Linux or Unix). But if you come from a high level language like Java (which is also performant by the way) Go feels like wearing a straitjacket! Go lacks the most basic tools which any seasoned developer can expect from a language (like generics). Just look at [my response](https://medium.com/@addamsson/this-article-is-wrong-in-so-ma...) to this topic elsewhere.
2. "Go lacks the most basic tools which any seasoned developer can expect from a language (like generics)"
3. "Go does not have a de facto build system and you can’t handle dependency management in an easy way" [2]
4. odd error handling
5. not a lot of libraries to choose from [3]
6. possibly more arguments that I missed when summarizing your post
The way you paint it, people would be stupid to use Go. However, thousands of very talented developers use Go everyday. How can you explain this disconnect?
[1] I like how you didn't say that Go "is not as fast as Java". That's a subtle, but important difference.
[2] `go install` is the build system and I have solved dependency management for myself with literally a small shell script [4], and an official solution is in the works [5].
[3] I never had trouble finding libraries for use-cases both common and obscure).
It's not really stupid, it can be misinformed, or just a matter of taste. For some people having a small couple of specific qualities of a language is more important (because they "like" them) is more important than even some objective overall quality/ease of use.
Many people are just forced to used it because the company uses it.
And of course, all the people who actually ARE looking for a "Better C" - then they will of course use something like Go. It would be very "stupid" to use Java in that case.
> The way you paint it, people would be stupid to use Go. However, thousands of very talented developers use Go everyday. How can you explain this disconnect?
Billions of people hold staunch religious beliefs, yet this doesn't mean they're stupid or mentally handicapped.
It is not about stupidity, more like the blub paradox. If you only know C and Go you have no idea why for example Kotlin would be better for the majority of the cases because to see it you have to use it.
I came to it from embedded C, and would not call it a better C. Not that it is bad. It is just a wildly different use case.
The lack of a preprocessor alone (as ugly as that may be) rules it out for a great many embedded and cross-platform scenarios. The binaries are also fairly enormous. 10M for a shell util on a desktop may be good enough. Beneath that level, it is a deal-breaker and a scandal.
Agree with the straitjacket part though. Comparing it to something like Clojure, the best I could say for it was, "At least I don't have to deal with the JVM..."
You are unfortunately right about the embedded scenario. It always ends up being a C/Go abomination - and eventually you end up asking yourself...why didn't I just use C?
Perhaps it's characteristic of all language discussions, but Go articles seem to generate an extremely polarized set of comments. My other favored languages (Common Lisp, Nim, Rust, Smalltalk) tend to do the same thing, but in Go's case the passion seems so... misguided.
In my opinion, Go is just such a bland-in-a-good-way language. And I enjoy writing it, for the record. Came back to it after a while not writing it and discovered warts I had missed before, but it's still pleasant. Can't help but think people just need to relax a bit when it comes to Go. Listen to Rob Pike speak about it compared to Rich speaking about Clojure: Go's not the language to get worked up about.
When "bland" means "prone to copy-paste boilerplate", its starts to sound less relaxing. It sounds more like tedious search-replace and looking for not making a typo when adapting the boilerplate to the next similar-but-sightly-different use case. It turns a developer back into a coder.
What Go takes away is mostly tools of abstraction. Some of them are removed for a reasonably good reason (hard to implement in 1.x). Well, people end up with codegen tools that replace not only templates and generics but also the C preprocessor.
I know this is about the weakest critique possible, but currently using Go, I know my next project won't be in it, simply for the impossibility to put an opening curly brace on its own line. Other languages that don't require semicolons at the end of a line have it, and even if they didn't, I'd rather have to put semicolons manually.. Go is "opinionated" I guess, but so am I. Whatever their target audience is, I'm not in it.
One thing I used to hate about PHP but then kinda grew to like was variables being prefixed with a $, as it makes it real easy to distinguish between functions and variables at a glance.
Other than that, it's just programming. For me, who is making really simple things, 99% of the work is figuring out the pseudo-code and data structures, if the language doesn't get into my way, they're pretty much all the same. I haven't tried Rust yet, but from a casual glance I do like what I see.
... curly brackets on new lines do work perfectly fine in case you're writing code on your own. As soon as you start working in a team and each team member starts to use their own formatting, it becomes super messy and unreadable.
Either you inforce a clear style guide which leaves you to explain the team why your style is the best, or you leave this task to the language itself and never ever have to start arguing about curly brackets, whether to use tabs vs. spaces, ... (I'll stop here).
But why should Go enforce it on behalf of everybody? A parser option to not automatically insert semicolons would be all I need, but no.
To me, even with super short lines, braces at the end of the line are messy, and consistently messy is still messy.
> Either you inforce a clear style guide which leaves you to explain the team why your style is the best, or you leave this task to the language itself
Which then leaves the language to explain why that style is best. Did Google ever do that?
Style guides are a matter of taste. None is better or worse. Yet, I really don't like discussing about my taste within a team of different tastes. It's like asking someone why he/she'd prefer black coffee over cappuccino. I'd prefer someone (or the language) making a clear decision upon code style and enforcing it rather than ending up with a messy, un-styled code base.
> To me, even with super short lines, braces at the end of the line are messy, and consistently messy is still messy.
To me, they're just harder to spot. I think having them on their own line "frames" the inner block nicely.
That said, brace location is not the hill I'm willing to die on. It's a minor thing, not worth getting religious over. For my own code, I'll do it how I want. For a team, though, consistency really does matter. I'll make my case, and then I'll shut up and do what the group decides.
(And actually, I think consistency within a file matters more than consistency between files, so I'm fine with "The file author/main maintainer sets the style for the file. If you modify the file, keep the existing style.")
But when the language/tooling enforces it, you've made language choice a proxy for style choice.
A large part of what makes me stick to Ruby over Python for example, is that I can't stand languages with significant indentation. It may seem minor, but it isn't to me, to the extent where I avoid Python whenever I can.
When your language enforces formatting like that, people will choose or choose away the language over the formatting.
It's that important. Especially with so many languages to choose for that you can often pick one that is sufficiently similar.
Go enforces a style because all code, written across different teams and organisations, should look the same so anybody can pick up anybody else’s code and read it with ease. There are no differing styles in different libraries. It’s very harmonic.
What I can’t stand in other languages is the Laisser-faire attitude regarding styles. Some people put whitespace here, some there, some put the curly brace here, some there. How about some consistency across all codedbases?
I'm not willing to put up with harmony at the cost of the code I have to spend most of my time reading being formatted in ways I don't find optimally readable.
Making people who care about formatting to the extent I do refuse to use the language is the cost of tools that enforce those kind of rules.
That's of course their choice, just as it is mine to stay clear of tools (and languages) I don't consider worth my time.
> A large part of what makes me stick to Ruby over Python for example, is that I can't stand languages with significant indentation.
More like 'consistent indentation' methinks.
I still have nightmares about trying to merge some GSOC student's code from their branch to trunk where the indentation was all over the place, it was so bad that lint couldn't even figure out what the hell they were up to --
well, I think lint was crapping out on macros more than anything but still...
So...someone got to put on their resume they did a GSOC for Blender but the work they did was basically wasted since it wasn't possible to clean it up enough to merge.
No, I very much insist on consistent indentation. Yet what I consider consistent indentation and what a given tool might consider consistent indentation does not always agree. But specifically with Python my problem is that I've yet to see any setup where things like e.g. cut and past works consistently without regularly mangling indentation in various situations. Then having the indentation convey semantics is a nightmare.
> One thing I used to hate about PHP but then kinda grew to like was variables being prefixed with a $, as it makes it real easy to distinguish between functions and variables at a glance.
This is great for a lot of code but it's probably my biggest complaint about the language these days. PHP supports first-class functions, which is great until you realize all your functions stored in variables have $ at the front. So now, not only can't you use $ to distinguish variables from functions (because sometimes they're both) but you have to remember if something is a Closure* or not.
* another minor pet peeve is that you have to explicitly tell a function what variables it can see from the surrounding scope, but all anonymous functions inherit from a class called Closure whether they can see anything outside their own scope (a closure) or not.
Our team uses snake_case for variable names and camelCase for function names in PHP to address that ambiguity.
To me, the limited scope of variables with respect to functions makes debugging and code reading much easier, since everything I need to think about within a function scope is explicitly defined.
It's a shame to choose or dismiss a language based on what is an accident rather than essential, but I understand.
I, for instance, are not a big fan of reading and typing Lisp/Scheme/*, pretty printing or not, even though I understand why it is the way it is, or whether its otherwise fascinating.
> I know this is about the weakest critique possible, but currently using Go, I know my next project won't be in it, simply for the impossibility to put an opening curly brace on its own line. Other languages that don't require semicolons at the end of a line have it, and even if they didn't, I'd rather have to put semicolons manually.
Go actually does use semicolons and the formatting has been forced onto users to allow easier automatic insertion of them. They were going to get removed but in the end it was easier just enforcing a format.
> impossibility to put an opening curly brace on its own line
I sincerely wish all languages with braces would have this feature! Even Javascript devs practically standardized in always putting braces at the end of the line. I prefer working with code that mixes tabs and spaces than with the old-ancient style of spoiling a nice and clean empty line with a brace (yeah, you can just leave a line empty if you want your code to look nicer and more separated).
Thank God I can do a lot of my work in Python and don't have to care about these things though. Would've been great if Go too borrowed the "indentation for code structure" amazing idea from Python ;)
I mean, really, even Lisps never put their parens at the beginning of otherwise empty lines...
That Go uses curly braces instead of significant whitespace was a conscious decision. I think it was Rob Pike who talked about how he got bitten by a subtle bug in Python due to overlooked incorrect indentation. Curly braces also make it easier to paste code into the correct scope.
Why can't I have my own outlook and priorities? Why can't I like what I at a casual glance at the Rust docs? When I say casual glance, I mean casual glance, and if I missed something really horrible, I'll find it soon enough once I started actually using Rust; but I'm not going to feel silly for something you can't even be bothered to point out.
People actually sit there and say not even having the option saves them discussions, and that's not satire? I program entirely for my own utility and artsy experimental purposes, so I don't care what is useful for teams, that is 100% irrelevant for how useful or comfortable a specific language is for me. Which is what my comment referred to, how much I enjoy, or not enjoy, writing in Go so far.
I didn't call the language bad, I even said I'm too much of a simpleton coder to to have much use for arcane differences. I just said that after not even having finished my first project in Go I can already tell you, without any irony, that this brace style being enforced is a deal breaker for me. I'm still finishing the project, you know. If people have all these great reasons for not minding the lack of an option and not even having a choice, why are they so insecure about one individual minding it? My comment went to +5 shortly after posting and is now at -2, I think that's just hilarious ^^
Some background. I actually wrote a semi-popular book on PHP (published by a major publisher) and have contributed to the core project. And I have spoken at many PHP conferences. Perhaps tellingly, PHP is rarely my first choice anymore. Which I think it a great language (contrary to many opinions) I just find other languages a better choice.
Today my language usage looks like this:
- Web services / APIs: Node.js [1]
- Front-ends that require easily modifiable templates and quick command line scripts: PHP [2]
- When I need speed and low latency for a network connected app: Go [3]
- When I need speed on an app that requires no network: C
[1] The promise chain asynchronous nature of Node.js makes it great for web services in my opinion. And the ability to easily have global variables that persist across connections for things like caching and pooling is a huge plus over PHP.
[2] PHP is very good at spitting out HTML and making web service requests, the performance is acceptable in most cases, and it is really easy for most people to edit, even people without a CS background. Likewise, for quick command like scripts PHP is unbeatable in my opinion. The tools it provides out of the box means most common command line tasks can be done 100% with the standard library. No package manager required. Though if you need to add packages PHP is pretty good about that now. Incidentally the fact the standard lib does so much is also one of PHP weaknesses. The standard library is a mess of inconsistently named functions and classes that grew organically over 20 years.
[3] I've saturated my loopback network interface on a non-trivial app on my Macbook Pro using Go. PHP and node don't even come remotely close.
I think this discussions are mostly pointless... Most of the times I can see one side or the other being right depending on the size of the project, size of the team, time to learn something new.
I guess the answer would depend on how many errors you have in the first place.
If you have a ton of errors, B is going to be more important. If you have relatively few, then A is going to be a lot better.
My employer would probably pick A, too.
But there's a hidden side to this: If it's that much easier to code quickly, it's probably easier to understand the code as well. Which means fixing bugs is faster as well. At least, in my experience.
> I have never had a framework project where I didn’t end up fighting the very system that was supposed to make development “easy”.
Not always, but often, I find this attitude in developers who either refuse to read documentation, or just entrenched in their ways and too stubborn to try it someone else's way.
Is every project you're starting really so cutting edge that the problems others have solved and come to a consensus on don't apply to you? Perhaps, but maybe you should also be taking a look in the mirror and making an honest assessment on just how difficult you are to work with.
280 comments
[ 6.2 ms ] story [ 369 ms ] threadAnd yet we keep writing Go.
By comparison, I'm a bit put off by the Rust community's evangelism, but that might just be my personal experiences with Rust community members.
I like it when they have a complaint but can see why the trade-off was made.
I don't like it when they're obviously parroting HN group-think.
I really don't like it when they have no complaints at all, but are able to recite the marketing happy-talk verbatim.
I admire people who can spot such things effectively and steer discussions in an productive manner. I see now that this is not really about interviews anymore but just everyday discussions.
What are the alternatives if you want something with type checking? Java? No, thanks. Haskel? Where are the libraries? C/C++?
I guess Typescript is the only alternative
https://github.com/spring-projects/spring-boot/issues/11343
The VO's I use trow exceptions when you construct them with some bad value. This is great because when you use for example a natural positive integer object you are sure it is one.
So now I have 'type checking' and more secure code in PHP.
http://php.net/manual/en/functions.arguments.php#functions.a...
And it is still the case with type declarations, that they make your code actually slower, because the runtime adds asserts in your code which gets evaluated at runtime?
But yes, if you're working on a modern PHP project, there's a lot to love: A solid module system, an enormous sea of high quality libraries, type checking, a really nice deployment and scalability story, decent performance, good tooling (IDEs, debuggers, etc.), a servicable C-style syntax. For many purposes (not all!) it's ten times better than, eg, nodejs. (Which might seem like a low bar, I admit...)
I quite like Typescript as far as syntax goes, but I think PHP 7.1+ is comparable. And PHP has a lot more support, libraries, and better tooling in my view. For example, my experience in node land is there aren't really any good ORMs; PHP has multiple, including one (Doctrine) which is easily the equal in my view of the highly regarded Python SQLAlchemy. Similarly with routing, frameworks, templating, etc., there's a huge amount of maturity on the PHP side that's missing from node.
The big question is going to be in the process model. Node has an event loop; PHP doesn't. For most purposes, I think an event loop makes writing good code harder to no real benefit, but in some cases (eg, acting as the endpoint for a ton of open websockets) it can be a big win. If you do need that, then you should probably lean towards node over PHP, and sure, why not use typescript? But for the general case, I'd still lean towards PHP.
(Then again, there's also a ton of other languages and frameworks. Just because PHP - or node - might be better than the other for some task doesn't mean there aren't a dozen more languages better than both.)
It's still the same as C, which is _not_ a solid module system.
https://getcomposer.org/
Though it has improved dramatically.
http://mypy-lang.org/
> Haskel? Where are the libraries?
Well, I suppose the same drawback would apply to Pony. :)
There's Nim and D too, but I get the lack of big commercial backing could disqualify them.
https://github.com/PatrickLouys/professional-php-sample-code
As for libraries, what matters is if the desired use case is covered, not winning the App Store count.
What libraries are missing? The only issue I've had with libraries are that some client libraries are wrappers over C libraries and this makes static linking difficult (or seemingly impossible on a Mac)
A few years ago there was a lack of libraries in some areas but that's not the case these days.
Other languages usually need a large number of dependencies, with Ruby and Node, often an entire build environment, with plenty of potential for dependency hell and hours wasted.
Some may advocate containers at this point, but it just hides the issue temporarily and may be too much for a certain category of end users. You now need to know how containers, ports, volumes and Linux systems work in far more detail when you actually just want to use an app.
Or look at Python, which is also compiled. Or Ruby, or JavaScript, TypeScript, Dart…
Does not matter where the implementation comes from, if it is free or commercial, what matters is that it exists.
Turbo Pascal compilation speed, in MS-DOS, using 90’s hardware was already faster than Go.
There are lots of languages with modules support, with static linking and native compilation to choose from.
In any case it doesn't change the fact that Go's compilation speed is nothing to brag about, it has been done before in many other languages, Turbo Pascal was just one example.
If you wish I can provide other examples of languages that compile as fast, on such old hardware while matching Go's compilation speed, with richer language features.
What relevance does this have on the compiler landscape today ?
If you have to use a compiler from ~30 years ago to find a comparison supporting your claim, it sounds very much like Go is indeed much faster than what it competes against today.
If you want the 2017 version of it, it is called Delphi. Beats Go in language features and compilation speed.
Go's compilation speed only surprises those developers that never used anything else beyond C and C++.
And beat 99% of other compilers today, meaning that overall compiler complexity has grown.
>If you want the 2017 version of it, it is called Delphi.
Ok, this is something actually relevant.
>Go's compilation speed only surprises those developers that never used anything else beyond C and C++.
For me (tm), Go compilation speed has compared equal or favorably against C, C++, Java, C#, Rust at least.
Which ones?
> For me (tm), Go compilation speed has compared equal or favorably against C, C++, Java, C#, Rust at least.
Since when does Go compile faster than Java and C#?
When I hit Ctrl+S my binary is already on the disk, thanks to incremental compiler integration on the IDE.
I have a full blown WPF application with multiple plugins, including data visualization, talking to Oracle and Postgres, total compilation time after check out 12s.
Eiffel, D, Nim, Jai are other fast compilation examples.
Java 9 added linking support for custom runtimes.
There are other C compilers to choose from, with libc implementations that properly support static linking.
Remember that Go is still a niche language, and the majority of programmers will never write a single line of Go.
There is a nice trend around Go nowadays, but most people are still writing PHP, Python or Java and Go isn't going to replace any of those.
Languages don’t get replaced, people just don’t use them as often for new projects.
Ouch, the lack of historical accuracy of your comment is painful. Just a few points :
- Sun Microsystem was founded in 1982, it's far from being a dot-com start-up.
- Java was already ubiquitous by 2000, it was embedded in your phones, your credit cards, in your browsers thanks to applets etc.
- in fact it did replace COBOL or C++ for a wide number of applications, not everywhere but it still had a enormous impact on the industry. Netscape even went as far as re-implementing their whole browser in Java[1]. It was a bad idea, but that gives you an idea of the revolutionary impact Java had.
Go is nowhere near where Java was in 2000, by several orders of magnitude. It's not a criticism of Go, I don't even think we'll ever have a language as popular as Java in that time, because in the 90s there was a massive window of opportunity for a language that was at the same time : safe, portable, and licence-free.
[1]: https://www.cnet.com/news/netscape-sharpens-javagator-plans/
Among the languages that came in last 10 years Go is most popular with exception of maybe Swift.
So compare to marketing juggernaut Java with billions sunk in by leading enterprise vendors Go is nowhere. But among non corporate driven language Go is definitely on top.
Go is indeed one of the most popular of the last 10 years, but I don't think it's the most popular one. Swift is way ahead (because of the iOS walled garden), and Typescript is probably more popular than Go (or at least in the same ballpark).
> But among non corporate driven language Go is definitely on top.
Go, «non corporate driven», really ? OK it's not «corporate-driven» like Java, but I don't think anyone would be using Go if Google wasn't behind it. I really think the impact of marketing in Go's success is bigger than its value-proposition (I'm not saying that Go doesn't have a value-proposition, I'm just arguing that marketing played a really big role in its adoption). Consider for instance the microscopic mindshare that Pony[1] has, despite being «Go from the 21th century» with a sound type system and a data-race-free concurrency model.
[1] https://www.ponylang.org/
Pony is also pre-1.0, and it doesn't look much like Go to me.
What I remember from the time was that C and C++ was everywhere, and Java was this weird new thing with a bunch of promises that ran slowly (because the JIT wasn't standard until later). There were a lot of people who were dismissive of Java, which was stupid, and there are a lot of people today who are dismissive of Go, which doesn't make sense to me either.
I think for many people, me included, it's flawed but good enough for the job and fun.
There's a huge fuzzy region between that extreme and "application programming as a semi-skilled trade", and go seems to fill certain "systems programming" needs adequately as far as that goes.
I think it's pretty well accepted that no systems language has GC. Go is on the same abstraction layer as Java/C#. Everything in text can be taken as a slight, and to ensure that doesn't read that way, I am a believer in targeting that level of abstraction most of the time. I think it's the sweet spot. I'm not a fan of the dual language approach targeting high (Python) and low (C). Java or C# makes more sense to me, for most software. That's my opinion. If I needed more than what those heavy hitters provide, I'd just go all the way and reach for Rust myself.
So I don't necessary see the parent comment from ctf as combative. I think he's just seeking accuracy.
I think the other commenter is correct: it seems like a semantics argument, and a rather pointless one at that.
I suggest reading Project Oberon source code, it’s freely available.
Back to Go, for anyone else reading this thread and wondering what Rob Pike thinks it is, evidence of them removing "systems programming" off their website is here. He explicitly states that he regrets it and that Go is not an OS writing language[0]. Andrei Alexandrescu offers a litmus test shortly after with a property of a systems programming language that Go also fails. If the creator of a language says it's not a systems programming language, I'm not sure how it can be argued by outsiders that it is.
If there's more damning evidence that Go is not a systems programming language, I couldn't imagine what that would be. A shortlist of systems programming languages that would pass any litmus test would include C, C++, D and Rust.
[0]https://www.youtube.com/watch?v=BBbv1ej0fFo&feature=youtu.be...
If you bother to read Joe Duffy's postmortems, and talks he has made about Midori, you will get it had nothing to do with technical issues, rather internal political wars at Microsoft.
Also Microsoft did not fully backed out, the outcome of Singularity became the MDIL compiler for .NET on Windows 8.x.
Midori influenced async/await, TPL, .NET Native used in UWP and the new low level language features on C# 7.x.
> If the creator of a language says it's not a systems programming language, I'm not sure how it can be argued by outsiders that it is.
I don't have Go in much high regard, but it certainly can be used for systems programming, and is being used as such today, regardless of what the anti-GC systems language crowd thinks.
"G.E.R.T : Golang Embedded Run-Time"
https://github.com/ycoroneos/G.E.R.T
"Fuchsia TCP/IP stack", all network requests go through it.
https://groups.google.com/d/msg/golang-dev/2xuYHcP0Fdc/tKb1P...
https://fuchsia.googlesource.com/netstack/
"Fuchsia disk management utilities for file systems"
https://fuchsia.googlesource.com/thinfs/
I did read Joe's blog, years ago. Your takeaway there also leaves you with a bone to pick with Microsoft, if it's just politics then you should be able to find someone in management at Microsoft to set straight. It'd be a real shame if there were no performance issues and it was shutdown due to politics alone.
That is a fact, easily validated in Fuchsia's repository.
According to you, Rob Pike should call management and let them know it is not a good idea to use Go for writing Fuchsia's TCP/IP stack.
You only read Joe's blog years ago, yet you missed the talks he gave.
Two years ago is not that long time ago,
http://joeduffyblog.com/2015/11/03/blogging-about-midori/
"My biggest regret is that we didn’t OSS it from the start, where the meritocracy of the Internet could judge its pieces appropriately. As with all big corporations, decisions around the destiny of Midori’s core technology weren’t entirely technology-driven, and sadly, not even entirely business-driven. But therein lies some important lessons too."
http://joeduffyblog.com/2015/12/19/safe-native-code/
"Over the course of 8 years, we were able to significantly narrow the gap between our version of C# and classical C/C++ systems, to the point where basic code quality, in both size of speed dimensions, was seldom the deciding factor when comparing Midori’s performance to existing workloads. In fact, something counter-intuitive happened. The ability to co-design the language, runtime, frameworks, operating system, and the compiler – making tradeoffs in one area to gain advantages in other areas – gave the compiler far more symbolic information than it ever had before about the program’s semantics and, so, I dare say, was able to exceed C and C++ performance in a non-trivial number of situations."
"Safe Systems Programming in C# and .NET"
https://www.infoq.com/presentations/csharp-systems-programmi...
"RustConf 2017 - Closing Keynote: Safe Systems Software and the Future of Computing"
https://www.youtube.com/watch?v=CuD7SCqHB7k
Around minute 30 he starts describing the uphill battle to convince other Microsoft teams to accept Midori achievements.
All of this was hashed out years ago upon Go's release, and the Go team took down the "systems language" moniker. That was the end of it. Google knows it's not going to fulfill stringent litmus tests for a systems-language. We'll review the subject again if the folks at Google are brazen enough to ever add it back to the website.
Now Rob doesn't have to call management and let them know it's not for systems programming, Rob & Google already know it's not. He said so himself. You're the only one in the dark on that front at this point.
Yes he did. He said it's a cloud-infrastructure language[0] and that he regrets calling it a systems language. That's why he took systems language off the Golang site.
>For fuck’s sake, give it a rest.
Why would we when we're right? Why don't you give it a rest, you've long been proven wrong.
You know, usage of the English language and the terms within matters. Claiming you have a systems language when you don't introduces confusion. You can loosen the terms all you want to but it will never change the fact that GC languages can never meet the strictest measure of a systems language. That's why it matters. No one should be apologizing to you because you don't like the facts.
[0]https://www.youtube.com/watch?v=BBbv1ej0fFo&feature=youtu.be...
Developers don't have to ask him permission or blessing for whatever they are trying to do with Go.
Google is using Go in system components in Fucshia, and the new GPU debugger for Android is also written in Go.
You are in the one in the dark about using GC enabled systems programming languages. I have real life experience using them and have seen it works.
I lost interest on Go due to its spartan design, but certainly will encourage anyone trying to use it to build an OS from scratch, regardless of what is written in a web site.
"They did not know it was impossible so they did it"
-- Mark Twain
A lot of things work, doesn't mean they meet strict litmus tests (which matter, because definitions matter), nor does it mean it's a good idea.
Anyone is free to just fork Go and do whatever they feel like with it, regardless of what Rob thinks. That is the beauty of MIT license.
So given that Oberon is accepted as a systems programming language in computer science, with multiple published papers and books across two decades, heavily used in OS research at a couple of European universities during the 90's and an influence to Go, with hardware and compilers still being sold for systems programming, although in small scale.
What are the actual technical features Go is lacking that makes it impossible to be used for systems programming, given Oberon's influence on its design?
1) A lot of things work, it doesn't make them good ideas.
2) Go doesn't meet the strictest litmus tests of a systems language, never did, never will. It's only a systems PL only if you relax your definition of what it is. Go's own creator says it's not and if any one person is the authority on this topic it's him. There are platforms that meet all definitions, those are definitely systems PLs.
I only care about what Computer Science books and ACM SIGPLAN papers accept as systems programming languages, not random opinions in online forums.
Thankfully both of our opinions are meaningless to Go users.
So we'll just settle on once there's a commercially successful operating system built in a GC'd language then I'll eat crow but till then they're all going to be C/C++/D/Rust or built on similar abstraction layers. Go ahead, wash away Linux, iOS and Windows in the competitive landscape with something written in Go. Let's see it, that's believing after all. It'll never happen because it's unsuited and inferior for that purpose.
crt0.o is a very simple set of startup routines with a fixed and predictable behavior. It is typically run only once ("0" in the name is for startup), and has only a couple of assembly instructions.
Colloquially, this. There's historically been a fairly big gap between "very little runtime" and "more runtime", so "no runtime" and "runtime" are what people say.
That said, the word is generally ill-defined; some people use it to mean "interpreter" or "vm" rather than the classic definition, which is (as you say) that every non-assembly language has a runtime.
;-)
Here's Rust's runtime: https://github.com/rust-lang/rust/blob/master/src/libstd/rt....
At ETHZ Oberon workstations were used during a couple of years by several users across the department.
Most of those attempts failed due to losing the political and financial wars of bringing them into the wider market, not because of lack of features.
Just because there is a GC doesn’t mean it is the only way to allocate memory.
Or not.
"Grail Quest: A New Proposal for HW-Assisted Garbage Collection" (PDF)
https://people.eecs.berkeley.edu/~maas/papers/maas-asbd16-hw...
Also Intel did have hardware GC with i432, but the chip suffered from many design errors that made it quite slow.
The way you say that, it sounds pretty unimpressive. Say, 2 years and 10 users, plus or minus one order of magnitude. That's not enough to tell anything. Was it going to be portable to other hardware? Was it going to be maintainable? Was it going to be comparable in performance? The answers are all "no data". The only thing you can say is that it could be successfully written and gotten to work, for a definition of "work" that allowed a few people to use it for a little while.
> Most of those attempts failed due to losing the political and financial wars of bringing them into the wider market, not because of lack of features.
Well... I wasn't there, but I took a look at the Wikipedia page (yeah, I know) giving the chronology of the Oberon OS, and it's quite unimpressive. For four years, it had "only simple text editing facilities". Those four years ended in 1991. That sounds very much like "lack of features" to me.
In particular, the competition was either DOS, Mac, or a Unix workstation. That feature set would not lead anyone to want to choose Oberon.
Now, I know, there were only a couple of people working on it part time. But all this really proves is that they were able to write an OS and get a text editor running on it. That's proof of concept, I suppose, but there's a huge difference between an OS like that and an OS you can "bring into the wider market".
I think you're idolizing a past that wasn't all that hot at the time...
In the meantime a new version of Oberon was re-done with Oberon-2, whose method declarations influenced how Go method declarations are done.
By this time there was a spin into a Swiss startup that designed Component Pascal, an Oberon-2 derivative, with a RAD development environment targeted mostly at Mac OS and Windows users.
The researchers at ETHZ created Blue Bottle OS, also known as A2, using Active Oberon. Yet another Oberon evolution, that had support for co-routines in async/await style, and probably one of the first environments with a multi-threaded compiler.
It was good enough to support applications like video playing, BeOS wasn't the only one doing it in the mid-90's.
If you want pictures, there are plenty of them here,
https://goo.gl/Rce7A2
Oberon was used until early 2000s to teach systems programming at ETHZ, and many department computers used them as their main workstations.
Including file servers implemented in Oberon for distributing work across workstations, and an early version of applets concept called Juice.
ftp://ftp.cis.upenn.edu/pub/cis700/public_html/papers/Franz97b.pdf
Graz University had their own variant of Oberon, with Hanspeter Mössenböck leading some of the development efforts. This same department is nowadays heavily involved with Graal research together with Oracle Labs.
http://www.ssw.uni-linz.ac.at/General/Staff/HM/Publications/...
http://ssw.jku.at/Research/Projects/JVM/Graal.html
The Ulm university in Germany also implemented their own Oberon variant, including native versions running on top of several UNIXes and Windows.
Mostly broken links nowadays,
http://www.mathematik.uni-ulm.de/oberon/ulm.html
Niklaus Wirth later in 2013 redid the original Project Oberon, with an updated variant named Oberon-07 and targeting an FPGA instead.
http://www.projectoberon.com/
So no, I am not idolizing a past and there was a little more there than just a plain text editor.
Sometimes the Wikipedia is not the best source.
Two years after that, Mickens wrote a glorious takedown[0] of Javascript--which must not have been as glorious as I thought--since people still seem hell-bent on using in as many places as possible.
Alan Kay said that computing is now a pop culture...
[0] https://scholar.harvard.edu/files/mickens/files/towashitalla...
The two languages are comparable at best in the amount of warts they have, while my firm opinion is that the js ecosystem is the most horrible thing in the world.
EDIT: p.s. thank you for designing your website so that can actually handle some traffic. That's worthy of the hacker news gold achievement
Not really. When I had a blogpost on the frontpage for the first time, I checked the monitoring and saw a CPU load of 6% of a single core and 1 megabit per second (that's bit, not byte). [1]
And it's simple, really. You just write some text on the page, add a small stylesheet. And then you just stop, resisting the urge to add any JS and tracking and hero images. You just stop. And instead of generating your HTML on the fly from a database, you just serve a static HTML file.
[1] Graphs: https://blog.bethselamin.de/posts/latency-matters-aftermath....
I must have links to at least five different gzip middlewares in my favorites, and I'm sure there are more than that...
At which point is it easier to put the app behind an nginx reverse proxy? Chances are that you have a reverse proxy anyway since one Go app is not nearly enough to saturate a server CPU.
Not hating on it though. I like Go for network-y things.
edit: And in your example, is it a clear win to centralize compression at the proxy?
Maybe the only thing I'd add is a compiler warning when an object which does not declare itself as interface X but complies to it is used as interface X. (Typeclasses would be even better, but it opens the can of worms which is the support of generics.)
Yes, Uber is running a production Go service with massive QPS. This is exactly what the original author meant when referring to Go's strengths with single-purpose, high performance, "nano" services with relatively little business logic.
There is also the insistence that frameworks are bad and developers absolutely have to care about "granular control" and "manipulation of bytes and bits" and packets and IO (unless they're writing a "glorified todo list") which rubs me the wrong way. Why is it so hard to acknowledge that there are a large number of perfectly good websites and codebases that do well with popular frameworks?
We ourselves have a proxy layer and a couple other services written in Go, and they work great, but the rest of our stack is Java and some Python. Developers are free to choose the best tool for the job when starting new project, but after a few days of messing around in Go every new service is undoubtedly built using our existing web stack.
> I’ve worked with RoR, and a variety of frameworks in the Node world – and I have never had a framework project where I didn’t end up fighting the very system that was supposed to make development “easy”.
This is not my experience with Rails, Django and Phoenix. Actually, I was probably fighting Rails in my very first project in 2006 (or was it 2005?) but I was writing it as if it were Struts (I was coming from Java.) Then I started coding as if it was Rails and got a great speedup in terms of coding time. I'm less proficient in Django. It seems that it doesn't really enforce a project structure and one can do almost what s/he wants. I've seen projects that look very different to a degree I never saw with Rails. Basically all Rails projects look the same. Phoenix is somewhat in the middle.
So, if the author is wrestling with frameworks either he's not proficient with them, but this doesn't seem to be the case, or he genuinely doesn't like to be constrained by the requirements of those frameworks. This is not a bad thing per se. If one feels like that, he's going to be a happier developer writing code with the architecture he designs. I'm not sure customers will be happy too, but I don't know what kind of projects and customers he has.
About me, I prefer to stick with standardized architectures that any developer after me will be able to understand in minutes. I'm a freelancer and I just don't have the time to spend a significant amount of my customers budget to learn (and make learn) more clever and optimized architectures before doing any real work. If I had my company running around one software product, then maybe I would design it from scratch. Reality check: I wrote so many MVPs in Rails, especially for customers. Given the usual outcome (failure to get traction) it would have been a waste of money to start with a more clever design.
For example, the labstack echo framework in Go is one of my favorite frameworks, it does a lot of work for me. On the downside, I can't hijack HTTP connections in the router, like for example, when I want to host something under customs domains and redirect internally to a subURL. I have to hack around the framework to do that, the solution is rather ugly. But there isn't much I can do otherwise that doesn't have various amounts of bugs.
Frameworks will always limit what you can do, period, you will have to code around them once you want to do something they don't allow out of the box.
On the other hand, the less the framework does for you, the less limiting it is but in the same moment it also does less work for you.
This isn't a problem with "frameworks" but a problem with the library you specifically chose which is bad since it doesn't even fulfill your needs apparently. I wrote my own go http router, and I have no problem hijacking the connection and filter according to hosts, at all.
I don't want to bother with writing my own router and this was one of the few times I had problems.
I think even if I wrote my own framework, I would eventually end up having to hack around it anyway when I inevitably need to do something the framework I wrote just fundamentally can't and I suggest this will be the case for your custom implementation too.
Suddenly, you'd like to have real-time comm? Don't add WebSockets, simply because they fit right above the whole of your stack based on HTTP. Use TCP.
There's a very gentle balance between using what you've already got and introducing a set of newer entities into the system; and sadly this is not always that clear, which one you should use.
A balance must be found, in one of the earlier examples, a quick hack was easier.
I'll be the first to admit that PHP certainly has it's share of really bad developers, but what language doesn't?
I could see how doing FORTRAN for a banking institution is a good way to make money; but PHP doesn't even have that.
Most of my closer friends with a Computer Science degree would probably try to stay away from PHP: neither does it pay better than other languages, and most of the companies that have chosen to work with PHP <probably> don't seem to be that appealing either.
Is that an old trope? Well, I am parroting the industry: I had worked with PHP and I had realised that none of the cool people with money would do PHP anymore. It literally is similar to not using git in 2017 - if you're still doing PHP, then you're probably a dying business or a really bad software house.
Unless you're doing web development. Outside of the HN bubble, there's still a very active segment of the software industry that uses PHP. Yeah, it's not a "cool" language or whatever, but experienced PHP developers can churn out solid work very quickly.
I made pretty good money as a PHP developer for a lot of years - you would not believe the places that this language gets used (and in what ways). "Dying business" is definitely not how I'd describe my past employers.
Also OOP in Go is perfectly fine.. it's just by composition only and without inheritance.
† Although they have their fair share of issues, this is not a jab at UML nor Java themselves, but the way things have been taught, terribly, for so many.
Some time later I learned Lua for fun and almost instantly understood what this whole prototype based programming / composition was about :)
TLDR: While I learned about composition at university, they failed to really show how it is used and what it is good for..
IMO it's much better to explicitly reference all mixins, and compose by reference rather than by direct inclusion, unless the composition has strong reliance on the identity of 'this' / 'self' in its implementation.
I have a vague working model of object orientation but a lot of the finer details go straight over my head.
I've heard other people speak similarly of learning Perl's MOOSE after already being familiar with non-OO Perl. This probably is no coincidence since MOOSE is heavily inspired by CLOS.
IMHO it doesn't matter much how much you read about the differences, until you get in there it won't do much good. This is a good place to have a throwaway project on hand, because your first try is likely to be a very big mess.
If you know an inheritance model and a non-inheritance model, you'll be well on your way to understanding the nuances because you'll have the experience in the field.
(For reference, my personal definition of OO is pretty much any language where you can write object.method(arguments), some kind of polymorphism is made available on that, and that is either the primary or a very important element of design in the language. It's a very expansive definition because I find that having massive definition debates about what OO is to be nothing more than useless flamewars.)
Which took C’s place for user space applications on Inferno, the last Plan 9 iteration.
Plan9 3rd edition was released June 7, 2000
Plan9 4th edition was released in 2002
This version went into continuous improvement mode, the latest commit in the tree was Apr 29 2017
I'd argue Rust is the "better" C. Go is a "simpler" C, at the expense of expressiveness, features, speed (only noticable in very low level usecases) and applicability for certain domains (Go is primarily for networked apps).
In the same way Java wanted to be a simpler C++ (which came with it's own drawbacks).
And for me Go is more of a competitor to Java (as Java is mostly used for networked applications) than it is to C.
Rust loves zero cost abstractions, and isn't afraid to be complicated. It gives the programmer as much power as possible.
Go is simple and actually very fast. The garbage collector is probably the biggest hurdle for performance and it's still best in class. Definitely higher level than C, but not enormously so.
C was also king of the zero cost abstractions.
> and isn't afraid to be complicated.
C sure is not afraid to be complicated. But at the time it was huge simplification. I'd say Rust's complexity is not there for it's own merit, but has huge advantages (though not that visible in a very small project).
> It gives the programmer as much power as possible.
C, C++, Rust are all in that corner.
Go obviously isn't.
C++ has static dispatch classes, templates, constexpr, and macros. C just has macros. Any other abstraction costs machine code. C++ also offers a lot of low cost abstraction like RAII-style scoping.
>C sure is not afraid to be complicated.
Not sure in what sense you're talking. C is not complicated. It's low level. It's exposing complications in the underlying model of a computer. Example: pointers in C are not complicated. Understanding how they work may be for beginners, but that just reflects how hard it is to understand what's going on in a computer.
C is accidentally complicated where it is flawed; the non-orthogonal behavior with arrays and the syntax for function pointers are examples. Go fixes some of these flaws, which is unsurprising since it was informed by people close to the origins of UNIX and C (y'know, like, Rob Pike?)
>I'd say Rust's complexity is not there for it's own merit, but has huge advantages (though not that visible in a very small project).
Sounds a lot like C++. It isn't accidental or coincidental that it is a favorite for high performance but complicated stuff like game and browser development. This is no surprise since Mozilla wrote it to replace usages of C++ for memory safety and concurrency, not because C++ didn't offer enough. C++ is flawed in ways Rust isnt, but that doesn't mean the two don't share a lot of traits, and it was Not by accident. Complexity is one of them.
>C, C++, Rust are all in that corner. > >Go obviously isn't.
Since you've offered no reasons for why this would be true, I can't actually refute it. But it doesn't make a ton of sense. Go and Rust both let you shoot yourself in the foot literally as much as you want. Go directly facilitates assembly code and allows direct memory access with unsafe. Rust also does this. Go tries to be memory safe and provide concurrency primitives. Rust goes about this in a different way. I don't see where they significantly differ.
Rust differs most in it's superior memory safety model and low cost abstractions. Go differs most in it's simplicity and built-in concurrency. But they both feel close to their own origins.
> Go differs most in it's [...] built-in concurrency.
That was what I was driving at, as well as Go not being fit for writing a kernel in. Sorry being so inarticulate.
On the other hand, I'm glad things are turning out the way they are. Rust and Go are both filling niches that C and C++ didn't, in ways that they couldn't have. I look forward to Rust-based OS kernels, for sure. It seems like with time, we can build very resilient foundations with Rust that wouldn't have been possible before.
You can use atomics and syscalls and even assembly in Go to have complete control over the system in the same way that you can in C/C++. It's definitely not trivial to bypass Go's memory model and get raw access to memory, but you can do it if you want. I'd say that Go discourages you from doing so, just the way Rust discourages the use of unsafe memory access even though you can if you want.
This I see as a stark difference.
Wrt concurrency, Go is more like Node: one way to do it.
Seriously? That's news to me. Only C zero cost abstractions I know of are based on external code generators. Or some macro abuse, but that's rather limited way to create abstractions.
But then again, when you really need to understand everything that is going on, abstractions are often not helping you.
(I write kernel drivers and bare bones embedded, where memory measured in kilobytes, not megabytes.)
It is worth noting that this was pre-PHP7. Post-PHP7 the out of the box performance is similar or better to what Facebook did with the HHVM.
99% of all PHP software will be fine with a quadcore server with 4GB RAM, running a LAMP stack. This can be scaled as needed (eg moving off mysql, adding a reverse proxy, real load balancing).
As stated above PHP7 has similar performance when compared to HHVM which was made by Facebook. Additionally PHP has an amazing performance debugger by FB called xhprof.
PHP performance could always be increased hugely by making sure is cache buckets have enough memory (opcode cache, realpath_cache_size).
Secondly with any web framework your app will most likely be limited by IO (database, file lookups, networking) before it becomes limited by actual code execution performance.
If anyone's ever worked on a project where the performance problem was the language and not IO I'd be really interested in hearing about it, but in my career of making websites I've never ran into this problem yet.
> Additionally PHP has an amazing performance debugger by FB called xhprof.
xhprof is unmaintained for years. The official version does not compile with PHP7. Various forks exist, but the only stable fork has been rebranded and defaults to sending all the performance data to the branding company.
> PHP performance could always be increased hugely by making sure is cache buckets have enough memory (opcode cache, realpath_cache_size).
Always, really? The history of PHP opcode's caches is complex. Before PHP5.6 where Zend published their opcache+, I've seen the various solutions (APC and others) cause vicious bugs.
> Secondly with any web framework your app will most likely be limited by IO (database, file lookups, networking) before it becomes limited by actual code execution performance.
I've seen quite a few PHP applications that were CPU-bound, and that were far from Facebook's scale. For instance, the learning platform Moodle is popular with universities, but getting it to handle hundreds of concurrent users cannot be done on a plain quad-core server.
Another poster suggested load balancing as an obvious solution, but adding this is not that easy. E.g. Moodle has to track various files, including uploads. So once you add a load balancer and several PHP servers, you need to use a network mount for most of your files, which has a big impact on IO performance.
I'm not saying that other languages are better, because I can't compare the exact same large application in two languages, but PHP7 isn't an Eldorado.
That depends if you set up cachefilesd correctly. Many people think it's enough to do the NFS mount and that's it, but it's not - NFS's mount parameters have a big impact on performance, and having cachefilesd enabled can make performance go through the roof, especially with big files. Without cachefilesd the only caching is in-kernel memory, which can and will lead to files being evicted from the kernel cache...
Same for MySQL - having configured it correctly (or incorrectly!) can make a life-or-server-death difference.
All without having to touch PHPs configuration... there's a reason why a good operations guy is worth his weight in gold.
Out of 8 downtime events, 5 were related to NFS mounts.
Such "hacks" have hit too many too big firms for me.
Out of interest, what issues have you had with NFS mounts? I run a fleet of virtual servers with their disks on an NFS-mounted NAS share and backed by cachefilesd, never had a problem with that setup.
It may be worth mentioning that we had decent throughput with NFS. Roughly 10 writes per second (from 100kb-250mb) and 20 reads per second (IIRC).
We use rclone to do a daily backup from primary -> secondary cloud file store, and use a little wrapper function in app to switch which host we're pulling files from so it's not too hard to failover during an outage.
I do agree with you about vendor lock-in though, it's nasty stuff. At the end of the day it comes down to time allocation. I'm a one-man ops show with too many other things to do than to wake up with a Pingdom alarm at 3AM because of NFS.
Might have been worth a try to get a RHEL support contract, but if you're a one-man show and happy with CDN, then that's the better solution for you definitely ;)
First of all realpath_cache_size is unrelated to opcache and has always worked well. The only problem with that configuration is that the default is waay too low for modern frameworks.
Also I think GP meant that now you can always finetune the opcode cache. The current opcache is built into php 5.5+ and just works. It works so well that there are almost no competitors because there is no need.
We are working on separating the extension that powers our SaaS APM for PHP and the original xhprof callgraph profiler again into two extensions in the near future :-) Then the extension will still be branded, but it has no code related to sending data to our service and just the backwards compatible profiling API.
But if you're building a big old MySQL CRUD app full of complicated business rules, PHP makes a lot more sense.
/s ?
Latency is additive; it's a sum() operation, not a max() operation. Yes, a large fraction of most web requests get eaten by blocking on IO, but everything on top of that adds up, and small numbers add up surprisingly quickly. And the more you try to be smart about that stuff, whether it's optimizing what you query, do extra caching, try to turn multiple DB roundtrips into a single trip, you often just trade IO time for CPU time (albeit lower). You still care about CPU performance.
This! And you can only discard some components latency when it disappears in the deviation of another components much larger latency. In most PHP (or Ruby/Python/etc for that matter), this is not the case. They add some 10-150ms on top, and often the db calls are <10ms.
Performance does matter, and is hard to improve once you have many KLOC of code in a slow language. Hence FB spend big bucks on PHP performance improvements.
Most are <10ms. Those nasty few ones with 100+ms (or sometimes 10+s!) are where the best money is spent optimizing. However good query/db schema optimization is a skill many developers do not possess... which is why a good DBA is worth his weight in gold.
Our company's product is CPU bound, and our language (Python) is definitely inhibiting our ability to meet basic performance goals. I've done a few crude benchmarks and I'm confident that a rewrite in Go would buy us at least a tenfold performance improvement, although the benchmarks themselves suggest it's closer to 100-200X. Besides being faster out of the box, Go is also easier to optimize--better profiling tooling but also the ability to control memory layout, allocations, and dispatch. And that's all without parallelism.
I don't think there's a virtual machine in Go.
In any case, the application is still CPU bound, thereby making it an example of a web application which is not IO bound, per the OP's request.
You can start with things like Cython which will give you a modest boost over plain python. I agree it may not be useful in your case, but doing full-rewrites are generally awful, abysmal and a nightmare all combined. Sure, there are cases where you must for various reasons, but they should be avoided if possible.
That's the beauty of doing something like an FFI with C/Rust/etc. You can iteratively move that direction, get code deployed faster and get your performance gains, while also slowly moving into a full-rewrite, but it can happen gradually and you get all the perf enhancements during the re-write, plus you get code deployed in production faster, so you can get all the code tested, and make end-users lives much better in the process of your re-write, instead of making them wait until the bitter end and then finding out that X, Y and Z undocumented features customers were using didn't get included in the re-write.
Anyways all that said, it sounds like you know what you are doing for the most part, so my advice here may not apply to you directly at all, and that's certainly plausible. But I think in general it's fairly obvious to experienced devs that re-writes are an awful plan.
Also one should not forget that a company with 1000s of engineers is probably not you (yet); when you read that some company runs successfully on Node and saves $n amount of money by using it etc; when they have 1000s of engineers and devops on top of that it doesn't mean you can achieve the same (or any) success with it with 2 people. PHP for instance might be a much better choice with a small team; you don't need complex server setup, you don't need (or can handle) middle of the night alerts that require you to dive in vs just reboot the server etc.
This is not so for Go or Node for most hosters out-of-the-box. Sure in the HN echo chamber, every hoster offers this maybe, but there are literally 100000s of small/big hosting companies/resellers in the world that run, say, CPanel. And the only thing that is trivial there is LAMP (with PHP/MySQL) hosting; the rest is just not very convenient or even impossible.
So once you set it up, no there is no difference, but then you have to know how to set it up, secure it, have access to set it up and secure it and know how to maintain it which is the point i'm making (not meant about specific environments besides PHP/MySQL); if you are a small company that needs to make money, you might not(!) want to bother.
Edit: Cpanel, in some near-future version will offer Node, I cannot find Go though.
Edit2: I'm definitely not recommending anything here or saying Cpanel is any good; I just know it well and I know that it's the most installed 'admin panel' on hosting servers.
You don't have such things in other languages simply because they have not been initially created as glorified templating engines. More importantly: for example, Django in debugging mode allows you to swap templates on the fly, so is with the executable code. Except nobody does it because that's considered ridiculous.
I don't think it was a very wise decision because not only are you doing things twice, you're doing it three times, because you have to serialize/deserialize to/from Thrift for every request. It adds development time, more tests, and Thrift's binary protocol makes debugging RPC almost impossible.
This isn't really an argument for/against Go, but it just shows that you should try to avoid using multiple codebases that have to be tightly integrated. Personally, I would've gone with a Ruby-only codebase that used Thrift RPC only if there was some backend task that was too slow in Ruby, and that Go's concurrency and speed might be better at. Then I'd serialize it and send it over to be processed by a better language. I wouldn't do it for every request.
That being said, if I had the choice between writing an API in Go vs Rails, I would do it in Rails for the faster iterative development speed and quick debugging capabilities that is made possible by an interpreted language.
https://github.com/yarpc/yab/blob/dev/README.md
Hard to debug binary-based RPC? You have picked the wrong technology for communication, having forgotten that you'd need to build the necessary tools in order to debug it. There's literally nothing wrong with binary protocols, except developers forgetting about the necessary overhead of re-parsing the passed data in the debugger. But it's not an overly expensive overhead, if the architect had taken this into account.
Having heard this point absolutely not for the first time, the only question that remains is: who and why did make a decision to have it this way?
If you come from C it is good, sure. And you can write big projects in it like in C (just think about Linux or Unix). But if you come from a high level language like Java (which is also performant by the way) Go feels like wearing a straitjacket! Go lacks the most basic tools which any seasoned developer can expect from a language (like generics). Just look at [my response](https://medium.com/@addamsson/this-article-is-wrong-in-so-ma...) to this topic elsewhere.
1. Go "is still not as fast as Java can be" [1]
2. "Go lacks the most basic tools which any seasoned developer can expect from a language (like generics)"
3. "Go does not have a de facto build system and you can’t handle dependency management in an easy way" [2]
4. odd error handling
5. not a lot of libraries to choose from [3]
6. possibly more arguments that I missed when summarizing your post
The way you paint it, people would be stupid to use Go. However, thousands of very talented developers use Go everyday. How can you explain this disconnect?
[1] I like how you didn't say that Go "is not as fast as Java". That's a subtle, but important difference.
[2] `go install` is the build system and I have solved dependency management for myself with literally a small shell script [4], and an official solution is in the works [5].
[3] I never had trouble finding libraries for use-cases both common and obscure).
[4] https://github.com/holocm/golangvend
[5] https://github.com/golang/dep
Billions of people hold staunch religious beliefs, yet this doesn't mean they're stupid or mentally handicapped.
The lack of a preprocessor alone (as ugly as that may be) rules it out for a great many embedded and cross-platform scenarios. The binaries are also fairly enormous. 10M for a shell util on a desktop may be good enough. Beneath that level, it is a deal-breaker and a scandal.
Agree with the straitjacket part though. Comparing it to something like Clojure, the best I could say for it was, "At least I don't have to deal with the JVM..."
In my opinion, Go is just such a bland-in-a-good-way language. And I enjoy writing it, for the record. Came back to it after a while not writing it and discovered warts I had missed before, but it's still pleasant. Can't help but think people just need to relax a bit when it comes to Go. Listen to Rob Pike speak about it compared to Rich speaking about Clojure: Go's not the language to get worked up about.
(Please put generics in Go 2!)
This. At least this is easily added.
But why there is "nil" in Go I find less excusable, mainly because this "feature" is not easily (impossibly) removed.
What Go takes away is mostly tools of abstraction. Some of them are removed for a reasonably good reason (hard to implement in 1.x). Well, people end up with codegen tools that replace not only templates and generics but also the C preprocessor.
One thing I used to hate about PHP but then kinda grew to like was variables being prefixed with a $, as it makes it real easy to distinguish between functions and variables at a glance.
Other than that, it's just programming. For me, who is making really simple things, 99% of the work is figuring out the pseudo-code and data structures, if the language doesn't get into my way, they're pretty much all the same. I haven't tried Rust yet, but from a casual glance I do like what I see.
To me, even with super short lines, braces at the end of the line are messy, and consistently messy is still messy.
> Either you inforce a clear style guide which leaves you to explain the team why your style is the best, or you leave this task to the language itself
Which then leaves the language to explain why that style is best. Did Google ever do that?
https://golang.org/doc/faq#Is_there_a_Go_programming_style_g...
https://golang.org/doc/effective_go.html#formatting
Style guides are a matter of taste. None is better or worse. Yet, I really don't like discussing about my taste within a team of different tastes. It's like asking someone why he/she'd prefer black coffee over cappuccino. I'd prefer someone (or the language) making a clear decision upon code style and enforcing it rather than ending up with a messy, un-styled code base.
To me, they're just harder to spot. I think having them on their own line "frames" the inner block nicely.
That said, brace location is not the hill I'm willing to die on. It's a minor thing, not worth getting religious over. For my own code, I'll do it how I want. For a team, though, consistency really does matter. I'll make my case, and then I'll shut up and do what the group decides.
(And actually, I think consistency within a file matters more than consistency between files, so I'm fine with "The file author/main maintainer sets the style for the file. If you modify the file, keep the existing style.")
A large part of what makes me stick to Ruby over Python for example, is that I can't stand languages with significant indentation. It may seem minor, but it isn't to me, to the extent where I avoid Python whenever I can.
When your language enforces formatting like that, people will choose or choose away the language over the formatting.
It's that important. Especially with so many languages to choose for that you can often pick one that is sufficiently similar.
What I can’t stand in other languages is the Laisser-faire attitude regarding styles. Some people put whitespace here, some there, some put the curly brace here, some there. How about some consistency across all codedbases?
Making people who care about formatting to the extent I do refuse to use the language is the cost of tools that enforce those kind of rules.
That's of course their choice, just as it is mine to stay clear of tools (and languages) I don't consider worth my time.
More like 'consistent indentation' methinks.
I still have nightmares about trying to merge some GSOC student's code from their branch to trunk where the indentation was all over the place, it was so bad that lint couldn't even figure out what the hell they were up to -- well, I think lint was crapping out on macros more than anything but still...
So...someone got to put on their resume they did a GSOC for Blender but the work they did was basically wasted since it wasn't possible to clean it up enough to merge.
This is great for a lot of code but it's probably my biggest complaint about the language these days. PHP supports first-class functions, which is great until you realize all your functions stored in variables have $ at the front. So now, not only can't you use $ to distinguish variables from functions (because sometimes they're both) but you have to remember if something is a Closure* or not.
* another minor pet peeve is that you have to explicitly tell a function what variables it can see from the surrounding scope, but all anonymous functions inherit from a class called Closure whether they can see anything outside their own scope (a closure) or not.
To me, the limited scope of variables with respect to functions makes debugging and code reading much easier, since everything I need to think about within a function scope is explicitly defined.
I, for instance, are not a big fan of reading and typing Lisp/Scheme/*, pretty printing or not, even though I understand why it is the way it is, or whether its otherwise fascinating.
:((((((((((
Go actually does use semicolons and the formatting has been forced onto users to allow easier automatic insertion of them. They were going to get removed but in the end it was easier just enforcing a format.
https://golang.org/doc/effective_go.html#semicolons
I sincerely wish all languages with braces would have this feature! Even Javascript devs practically standardized in always putting braces at the end of the line. I prefer working with code that mixes tabs and spaces than with the old-ancient style of spoiling a nice and clean empty line with a brace (yeah, you can just leave a line empty if you want your code to look nicer and more separated).
Thank God I can do a lot of my work in Python and don't have to care about these things though. Would've been great if Go too borrowed the "indentation for code structure" amazing idea from Python ;)
I mean, really, even Lisps never put their parens at the beginning of otherwise empty lines...
Leaning towards “satire” based on your last sentence.
Let us all know if I was right.
People actually sit there and say not even having the option saves them discussions, and that's not satire? I program entirely for my own utility and artsy experimental purposes, so I don't care what is useful for teams, that is 100% irrelevant for how useful or comfortable a specific language is for me. Which is what my comment referred to, how much I enjoy, or not enjoy, writing in Go so far.
I didn't call the language bad, I even said I'm too much of a simpleton coder to to have much use for arcane differences. I just said that after not even having finished my first project in Go I can already tell you, without any irony, that this brace style being enforced is a deal breaker for me. I'm still finishing the project, you know. If people have all these great reasons for not minding the lack of an option and not even having a choice, why are they so insecure about one individual minding it? My comment went to +5 shortly after posting and is now at -2, I think that's just hilarious ^^
Today my language usage looks like this:
- Web services / APIs: Node.js [1]
- Front-ends that require easily modifiable templates and quick command line scripts: PHP [2]
- When I need speed and low latency for a network connected app: Go [3]
- When I need speed on an app that requires no network: C
[1] The promise chain asynchronous nature of Node.js makes it great for web services in my opinion. And the ability to easily have global variables that persist across connections for things like caching and pooling is a huge plus over PHP.
[2] PHP is very good at spitting out HTML and making web service requests, the performance is acceptable in most cases, and it is really easy for most people to edit, even people without a CS background. Likewise, for quick command like scripts PHP is unbeatable in my opinion. The tools it provides out of the box means most common command line tasks can be done 100% with the standard library. No package manager required. Though if you need to add packages PHP is pretty good about that now. Incidentally the fact the standard lib does so much is also one of PHP weaknesses. The standard library is a mess of inconsistently named functions and classes that grew organically over 20 years.
[3] I've saturated my loopback network interface on a non-trivial app on my Macbook Pro using Go. PHP and node don't even come remotely close.
If you have a ton of errors, B is going to be more important. If you have relatively few, then A is going to be a lot better.
My employer would probably pick A, too.
But there's a hidden side to this: If it's that much easier to code quickly, it's probably easier to understand the code as well. Which means fixing bugs is faster as well. At least, in my experience.
Not always, but often, I find this attitude in developers who either refuse to read documentation, or just entrenched in their ways and too stubborn to try it someone else's way.
Is every project you're starting really so cutting edge that the problems others have solved and come to a consensus on don't apply to you? Perhaps, but maybe you should also be taking a look in the mirror and making an honest assessment on just how difficult you are to work with.