When I initially started Go, it felt so easy to pick up. Then I wrote a component in it and it felt overly verbose. Then I had to revisit the component and had to do some heavy refactoring/additional testing and realized that the language, to certain extent, didn't stand in the way. After all these iterations, I think Go is leaving an-even-bigger-adoption on the table for the want of following:
1. Functional operators like map/filter/reduce - all of these would be optional but would save SO many lines of code.
2. Add simple conveniences - e.g. "contains" to check if a key is present in a map. Again those who don't want to use these, don't have to.
3. Error handling boilerplate - something to the tune of "?" operator in Rust
> 1. Functional operators like map/filter/reduce - all of these would be optional but would save SO many lines of code.
But at the cost of performance; Go is not (yet?) optimized for functional programming constructs, and its function syntax adds a LOT of mental overhead to reading the code; http://www.jerf.org/iri/post/2955 was a good post on that. Remember the Go proverb: clear is better than clever. In this case, not only for readability but also performance.
I have no objections to your point #2 though, I always found Go's constructs like `len(slice)` or `slice = append(slice, value)` a bit awkward. With generics support, `slice.len()` and `slice.append(value)` should now be possible. Actually I'm not sure why the latter was not possible all along, I'm sure there's a reason somewhere. I know you can implement the latter yourself as well, even before generics.
As for #3, I got nothing; I sorta followed along with a Big Discussion about different error handling in Go a few years ago, but it basically ended with "Well... actually how it is now is absolutely fine"; all the offered alternatives added complexity, magic behaviour, or reduced readability to the language. As it is, error handling is obvious. I wouldn't mind some syntactic sugar though; a one-line error handler at the moment is `if err := doSomething(); err != nil {` which is a bit awkward. The other Issue I have is with variable reuse and shadowing, it's a risk that may cause unhandled errors.
The examples of what map, reduce etc. could look like in "Why Go Getting Generics Will Not Change Idiomatic Go" are very awful, but chiefly because they repeatedly state many types that in most programming languages would be deducted or unneeded.
should contain no occurrence of 'bool' (it is implicit in the definition of a Filter) and at most one occurrence of 'string' (it is a filter over a string sequence if and only if the input of its defining predicate is a string).
Is there any alternative technique for functional style in Go?
>When I initially started Go, it felt so easy to pick up.
Same. It felt freeing to just say "fuck it, I'll use a struct" and have the built-ins required to automagically marshall json on the wire to structs in memory. That was pretty cool. You're spawning threads^H^H^H^H^H^H^Hgoroutines and passing messages and not giving a fuck because the language protects you.
Then I wanted to make v2 of my package.
Go's packaging (and module) system is just so indescribably, generally, and thoroughly bad that it put me off the language and I won't be back. I spent more time fucking around with dependencies and wondering why `go get` was giving me cryptic and unhelpful errors that were unaddressed by the docs than I did writing my code.
1 and 2 are now possible to implement, since 1.18 - I'm using this and it does save quite a bit of boilerplate: github.com/life4/genesis
I'd love to see less verbose error handling too, but Rust's ? IMHO is not the best way to go - it adds quite a bit of magic and makes debugging difficult, when a question mark at the end of a line "injects" an unexpected return statement.
And then we have folks running silly function calls for the sake of avoiding mutability.
Don't get me wrong, I understand why this hasn't been done.
We've all read the arguments against adding things to the language, but I accept in part, and reject in part that argument. Complexity always increases, so it's understandable to put the brake on run-away complexity. But GO is slightly pathological when it comes to the avoidance of adding sensible language features. The thing is most folks would rather have a slightly more complex compiler than a limiting programing language.
I know zero go, despite having worked with it professionally for a short stint that I try and block out of my memory (not go's fault), anyway that first example looks like gibberish to me while the second is super clear.
FWIW i also know zero Go but the first example made sense (though while i don't know Go, i do know it has multiple return values): the "m[key]" part returns two values which are assigned to the "_, ok" expression which represents a value to be ignored and an "ok" variable which is later used in the "; ok" part (i guess ; separates multiple subexpressions similar to C's "," and the overall expression's value is the last subexpression) and so the two values returned from "m[key]" are the map's value and a boolean (or something that can be used like that) that checks if the value was found. In which case "if _,ok := m[key] {" would be the same as something like "if m.contains(key) {".
Of course this is all guesswork based on similar stuff i've seen elsewhere, so i might be off, but i think despite not knowing the language it still looks readable if you know any other mainstream language (and exercise some guesswork/imagination :-P).
Well, that's because you do not work with go much I guess?
I can say the same about Fennel, List or Haskell.
The first example is the way to go in Go. It's idiomatic, not a hack. And it works the same way for many things (for example checking if a channel's closed)
Your parent knows how's to read code and can recognize the purpose of the second statement but not the first. While that is not some end-all metric, it does says something about the Go idiom's clarity.
It is. Because everyone starts out knowing zero go, and so the learning curve of a language (and for people who know another programming language first) is very much a key metric.
I know pretty much nothing about Scala. Anybody cares for my criticism of its type system? And what's with Rust and those ampersands everywhere?
GP wasn't discussing the language in general, just a small feature that depends on an idiomatic pattern used in many other places, saying "it looks gibberish." Of course it does, because it isn't idiomatic for you.
You don’t need to know that to do the comparison. If I tell you to do the same thing in one language it’s “(!:;$&)” and in another it’s “array_contains”, you don’t even need to know the languages to have a reasonable opinion on which is superior.
No, but IMO the cognitive load for the second one is a lot lower; it says what it does, not how it does it. It's like using `for i := i; i < len(slice); i++` vs `for i in range(slice)` or other languages' versions thereof; it reads in what you want it to do instead of how it should do it.
It's less about length of code and more about cognitive load; this is why functional programming constructs are frowned upon in Go code, because the cognitive load per line of code is much higher.
Also `if m.contains(key) { }` is even more obvious IMO.
I don't know about null, but wouldn't sum types and pattern matching make the language spefication and the toolchains a lot more complex? Their goal has always been to be simple and have longevity, but I think it's been at the cost of "safety", e.g. being able to just ignore errors, allowing nulls (although that's only for pointer types, value types have sane zero values and should be used as much as possible; some pointer types can handle null values as well), etc.
That said, there are other languages with proper sum-types and pattern matching, if that's what you need; I think it's a bad thing that some people advocate for every language to have every feature from every other language. Take Javascript; someone Decided that it should have classes, but the implementation has never been good (e.g. field access levels) and it's always felt bolted on. Take Scala, which borrowed every feature from every other language ever, and now you can't have two people work on one Scala codebase without them having endless discussions about which flavor or pattern to use.
> I think it's a bad thing that some people advocate for every language to have every feature from every other language
Not what I'm saying. I'm saying when smart people created Go, the forgot that null is a mistake, and sum-types are simply too useful in modelling the world to miss out on (pattern matching makes them a joy to use).
This was both well understood in the 20XXies; and I have never seen any reason from the creators of Go as to why...
> Scala
Scala is a multi-paradigm lang; that sucks on whole different levels. I'm not advocating at all that Go should be multi-paradigm.
The rats are leaving the sinking ship, is what comes to mind.
Go has become so mainstream and the talent has moved on.
I see it in so many cases.
Established packages only do dep upgrades and rarely add any innovation anymore.
Many of the original writers have abandoned the projects. Skeleton crews remain which lack the talent to be creative.
Gin for instance has a broken streaming api. No one is going to fix it. It would mean rewriting it from the ground up. Their contrib packages are mostly outdated and not functional.
Gorilla is also in maintenance mode.
The talent is leaving Go.
Go is also missing "the one true framework", e.g. what Spring is for Java. Or rails for Ruby or dotnet for C#.
I've been with Go since mid 2013. I loved the Go+ community on Google+. I loved the language because it removed a lot of mental burden and allowed me to focus on problem solving instead of listening to people telling me "what's proper" when I had done it my way for 13 years before the new hype, successfully.
I loved the bright minds using and developing Go.
But now it feels like it's dying or stagnating.
I thought spf13 was a company, not a pseudonyme of a Google employee. I use cobra in 99% of my projects, but cobra and viper leave much to be desired especially the interoperability out of the box and documentation.
This much more clear and honestly more impressive (because the first four are so obviously group effort that I discounted the last two - I had my suspicions about spf13-vim, though).
No, Steve that is not accurate. You didn't build MongoDB, Docker or Go. They were all wildly successful before you came on board. It's dishonest of you to insinuate that you built or helped build the core products. I can speak first hand for 10gen. For Docker you were not even there for a year, and for Go Rob was pretty clear who helped build it - Ian, Russ, Adam and a long list of people. You were ancillary involved around the periphery of all these.
Having worked on all these should be good enough you don't need to embellish and constantly overstate and lie about your contributions. Let other people talk about how great you are.
I think your wording was fine. I didn’t read that into it at all. Of course you worked with folks to do them. You also spent the majority of the post thanking people you worked with.
I’ve also read your code. I enjoy it and learned a lot more of go that way.
Whatever. Thanks for helping make Go so much fun for me. I look for excuses to write CLIs with Cobra/Viper. They’re of a very few set of libraries I look forward to using.
I use Hugo for much more than it was intended for.
Heck, I wrote a CLI with Cobra around Hugo and a simple theme for my personal note taking and todo management. I was annoyed with other markdown note tools and DIY was a fun waste of time :).
Steve is a very accomplished programmer, with what hugo / viper became in the go ecosystem by itself. In my view, the projects also jumpstarted a lot of new users who were trying out golang who weren't sold on it yet. I didn't really notice his leadership or advisory roles until now, that's just icing on the cake.
Thanks for your contributions, Steve!
Edit: If it's really big ecosystem, _indirect_ contributions also matter. e.g. in python, even if you're not writing CPython patches or PEPs, community based projects do a lot to shape best practices and even bubble up into standard library.
This specific, quoted, phrase doesn't bother memuch, but I agree that reading the whole article gave me, from top to bottom, a sour taste of personal branding and developer marketing that really doesn't sell it (to me).
Afaik the last 3-4 are actually largely his personal projects that he probably built most of himself. But yeah, kinda agree for the other ones, the phrasing feels a little self-aggrandizing to my ear. Not sure how intentional it is though, that kind of phrasing I think sort just sneaks into the lexicon for some.
Have you found Googlers to be self-aggrandizing on average? That's not been my experience working there. (But might be different for "Googlers who talk a lot/are well-known publicly".)
It's our way of trying to make something out of all the lost years working away in the salt^H^H^H^Hprotobuf mines. We have to use the 'leverage' because all else we'd have left is money in the bank account and skill sets incompatible with most other places in the industry.
Right, that's what I meant. I don't think the average Googler is self-aggrandizing, but if you don't work at Google or have a big friend circle that works there, then there's a selection bias for the Googlers you do know.
I know an MIT PhD (natural sciences) who thinks too highly of herself--when I beat her in the Chinese game of Wuziqi (She's Chinese and has beaten the computer and played nearly all her 20+ years), she was so pissed off....She still had that hubris and self-aggrandizement though, until she discovered by chance, that I used to teach mathematics at one of her Alma maters. After that she became sort of an enemy. This is the problem with self-aggrandizing people.
Yeah, wow, exaggerations everywhere ! Very distasteful.
His LinkedIn profile says:
"I’m responsible for taking Go Language, Docker and MongoDB from niche technologies to widespread mainstream enterprise adoption."
Yeah, he's a consummate self-promoter and exaggerator I was at Mongo at the same time. He worked on the drupal website which was a godawful mess. Then there was the Drivers team. He spent 3 years there, was absent most of the time working on Hugo while employed at Mongo. Mongo probably owns most of the IP for it. I am not sure what he did at Docker but he'd like you to believe the 10 months he spent there was pivotal to docker adoption, nevermind the fact it was already on fire.
While it may be read as some sort of Jealous screed, I have observed similar behaviors from people who fall under this collection of traits. People that might at first be seen as having accomplished a lot, but on further examination, its maybe a few things, and the rest of the things are generally exaggerations.
To a certain extent I understand the need to self promote if one wants to continue to work on OSS but without corporate sponsorship/funding.
Jealous? NO. Someone just needed to finally call him out on his bullshit.
He left in the middle of 2014. He was checked out for a long time. I'd say that timeline adds up pretty nicely.
So while Steve would like take credit for Mongo's enterprise adoption he barely had anything to do with it. Not with the Server, not with Cloud, not with Sales, Marketing or Education.
What a strange world 2022 is, wherein former employees of MongoDB openly catfight on HN over who was most responsible for suckering some of the Fortune 500 into buying a truckload of technical debt. Arguing over that like it’s taking principal credit for achieving sustained cold fusion. Baffling.
We all contribute to poop. Our level of contribution to said poop does not diminish that, in fact, we all work on poop so we’re all in the same poop boat. Take it easy on each other, and reserve the bullshit calling for those who really earn it, like the folks who initially built the poop you’re claiming by cleverly offshoring their minimum maturity on the financial and sweat equity of every early adopter. Like, say, for example, for no particular reason, my team at the exact time you’re arguing about.
It’s fine, though, I get it, that’s valley capital, fake it until you make it, give us ops teams ulcers, we make goodish money. Just weird to see resentment over who can claim MongoDB success with that kind of perspective is all. Particularly since the success at the time was all lazy developer mindshare (no disrespect, I’m lazy too), and the technical weaknesses started a few ten-year roadmaps that are now in the market and obsolete MongoDB.
> responsible for taking Go Language, Docker and MongoDB from niche technologies to widespread mainstream enterprise adoption.
In terms of proliferating Go I think that statement is fair. spf13 is like brand name in open source.
I recall years back on GitHub, spf13 was like a name you were guaranteed to come across if you were sinking your teeth into Go. I ended up using cast / viper: https://github.com/tony/vcsync/commit/a76681b. (Not that I'm anything special at golang)
To be clear, nobody is claiming that he didn’t write viper, or that he isn’t a brand name in OSS. The claim is that he was responsible for “taking go language from niche technologies to widespread adoption”, which seems like a pretty big one to make.
No doubt his contributions did in fact help that process, but as I read it, the claim asserts him as the driver of that process, which he was not.
In contrast, I think someone like Fabrice Bellard could absolutely use such phrasing without overselling himself... but then again, Bellard doesn't seem to exactly brag about his accomplishments either.
> Am I the only one who finds that type of phrasing distasteful?
Generally, I'm with you. In this case, I'm only half with you (the phrasing around Go and Docker could use some humility), but he really did build Hugo and Cobra. He contributed quite a bit to the Go ecosystem, he's not just some product person taking credit for work other people actually did.
These comments are why i stopped sharing my work. You can clearly tell that it is not the authors intent but someone (you) will always take things personal when given the chance.
A tree is just a type of graph. A graph can be represented as an adjacency matrix. So come up with that matrix, then drop it into lapack for inversion. Lapack is well optimized so this is probably a very good solution.
I haven't thought about this before, but I can't see how this would work. Instead, you'd convert to an adjacency matrix (with edge directions by only populating the upper rectangular region), then transpose the matrix, then convert back to a graph. The transpose should swap the i, j pair edge directions. Matrix inversion is super-expensive and I think it would produce somethign else entirely, probably not unlike matrix decomposition, which can extract centrality properties of the nodes. But it's super expensive.
Something obvious that I missed which sort of spoils the joke is that if you take a binary tree, look at it as a directed graph, and then take the adjacency matrix of the graph, it is obviously not invertible. Do'h!
I don't think that's true- at least, I see literature saying that inversting the adjacency matrix of a graph is useful. Is there something about the property of the graph that makes it non-invertible?
In the case of a binary tree, though -- I guess it depends on how you think of the graph. If it is directed -- a parent only points down to it's children (so, no backwards links up the tree), the adjacency matrix is clearly rank deficient. The row (or column depending on how you want the adjacency matrix to be set up) for edges going in to node 1 is empty.
If we think of the graph as undirected, it is still not invertible, but I don't know that there's anything immediately intuitive about it. With 7 nodes we'd have (numbered as in a breadth first traversal):
. 1 2 3 4 5 6 7
1 0 1 1 0 0 0 0
2 1 0 0 1 1 0 0
3 1 0 0 0 0 1 1
4 0 1 0 0 0 0 0
5 0 1 0 0 0 0 0
6 0 0 1 0 0 0 0
7 0 0 1 0 0 0 0
Rows 4 and 5, as well as 6 and 7 are clearly degenerate (all the leaf nodes).
The area between graphs and matrices is a productive one for mining ideas out of, because they are closely related but our mental models of them are pretty different. That group thinks there are enough good ideas in the space that it is time to work on a nice, solid building-block library. They've got some pretty well known researchers on board so I bet they are right.
My suggestion was just a joke, though, I don't think the inverse of the matrix that comes from a binary tree has any particular meaning.
About 10 years ago, spf13-vim showed me what vim could be and changed my coding life forever. I finally ejected it and spun my own .vimrc a few years ago, but I wouldn't be where I am today without it.
As someone who uses VS Code as their daily driver, I'm starting to tire of it and was considering trying out emacs or vim. Would you say spf13-vim is a good starter resource (curated plugins and all) or should I look elsewhere as a beginner?
Technically I don't think "author of article says they can confirm that numbers they used in their article are accurate" really holds up as a valid argument ;).
Tongue-in-cheek feedback aside, congrats on all your achievements and good luck on your future projects!
Anecdata: I've been doing all my projects in Go for many years now. My current production backend with 20+ services all run in Go on Kubernetes and serve 100k+ users.
It's an amazing language since it's so productive. Sometimes I write services in on go (pun intended) for an hour and after turning it on it just runs. Never experiences something like that with another language.
It's also very low on resource consumption. My server barely needs anything to serve that many users.
Snowflake and Databricks also hoover up a bunch of engineers, snowflake in particular extracted a large number of extremely senior folks. I assume they match base comp, offer equity, and then give people a lot more freedom than they would have at BigCo.
“I led the team that designed MongoDB’s pioneering user experience."
Let's break this down and I'll explain why he is a total liar and bullshit artist.
This makes it sound like he designed the mongodb query language. Only he could pass off inflicting the crappy Drupal website as designing MongoDB's pioneering user experience. He can't be talking about MongoDB the company, it was 10gen so obviously insinuating it was the DB.
The entire Driver and integrations ecosystem had to be cleaned up. His mess. Was barely ever in the office.
MongoDB user manual? You mean the book that Kristina wrote - who worked on the Server team and had nothing to do with you.
I know nothing about the parent comment but to be fair, he has only 12 commits with about 600 total line changes (additions and deletions) which places him 50th on the contributor list. That doesn't mean much in regards to spf13's involvement.
Well, you’re not really giving concrete examples that check out.
> This makes it sound like he designed the mongodb query language.
While I suppose spf13’s LinkedIn page could all be made up, it backs up the claim being made—that you quoted!—which is that he led the team, not that he was responsible for the design. Also, while “user experience” is pretty squishy, nothing suggests he was talking about whatever crappy Drupal web site you think is crappy.
> MongoDB user manual? You mean the book that Kristina wrote
I presume you mean Kristina Chodorow, who wrote MongoDB: The Definitive Guide, which is not the user manual. Again, the LinkedIn page could be entirely banana crazypants, but it says he led the technical writing team, which would have been responsible for the user manual.
Your post has a very, um, personal ring to it, like you were part of one of spf13’s teams and thought he was a bad manager, or maybe came in after he did and “cleaned up his mess.” (Something I’ve found happens virtually any time someone in that kind of position leaves any company, since “mess” can mean “actual mess” or “thing that worked fine but accumulated a lot of technical debt we are now stuck with”.) Maybe he ran over your cat. My point is, nothing you’re pointing to as evidence of him being “a total liar” appears to actually be a lie.
I built and led the team that was responsible for the MongoDB user experience. We designed and built MongoDB's integrations with programming languages & third party systems (Drupal, Hadoop, Storm, Spark, etc). Our team wrote the MongoDB user manual too and we were responsible for the websites.
My blog has a lot of talks / posts about the work our team did if you want to read up more about it.
Thanks, appreciate your response! Didn’t occur to me that you were talking about the UX for the entire ecosystem. Will read your blog for more details.
I started learning Go maybe 2 months ago, and we're now using it at work in production for small-scale projects, with plans to make it our default server-side language. The onboarding experience has been quite easy and effective I must say.
I have only written javascript for the past ~5 years and while I've never gone bored of writing code in a ~15y career, Go has brought some pleasant freshness to my work.
All that to say that this guy and the whole Go team have done some good work.
JS was an awesome refresher, especially as React came about and front-end dev became fun with any challenge; while backend seemed mostly mundane crud. Go re-ignited my passion as an engineer, and has been such an awesome tool in the age of microservices and performant distributed architectures. We're running large ML model architectures at scale with Go now.
A bit off topic, but does anyone else find a data/financial company name "two sigma" to be...either troubling (how often two sigma events happen randomly and their lack of meaning beyond random fluctuation), or really on the nose?
A few more off-topic thoughts about this comment: (a) Two Sigma is an investment firm (a wrapper around a hedge fund), not really a financial company, (b) pretty much no one at Two Sigma is unaware of how often 2 sigma events happen, so I think neither? and (c) two sigma events can totally have meaning beyond random chance, in fact they're usually a leading indicator that there is some connection beyond luck :).
All this time I thought spf13 was just Some Guy that did a pair of libraries for CLIs in Go, I didn't realize they were such a big contributor to the Go community. Thank you for helping the language escape its "this is a tool by Google for Google to fix Google-scale problems at Google" reputation; I've used it at a previous project for 2.5 years, it has its issues of course but overall I would use it again, in big part thanks to the community and resources available.
This article made me _really_ curious what manner of awesomeness is going on at Two Sigma, but couldn't figure it out from the website. @spf13, any pointers on where to find a good article on why TS is cool?
Honestly, most boutique, government-involved security consulting firms have similar requirements. Given how much of tech is outsourced these days, obscurity is often the only line of defense some organisations have.
Can’t speak for two sigma but I work in a similar company. They are generally only open enough to hire people, there is a huge competitive advantage in sharing as little as possible.
Lots of finance firms have a bunch of interesting problems, from scaling to security and many are getting better at treating engineers well. But usually it comes down to the fact they pay really well.
> This article made me _really_ curious what manner of awesomeness is going on at Two Sigma
This is probably a major reason he’s being hired.
I haven’t experienced too much of this phenomenon but “famous” OSS folks get coddled and showered with money by many companies in hopes of attracting talent.
And to be fair, its not the worst strategy. Instead of some silly values document they pay real engineers and usually give them a ton of freedom.
GOOG is no longer known for high pay. Given the same level, even Meta has exceeded Google pay for a long time now. That's not to mention hedge funds like Two Sigma or Citadel.
This is what I miss the most nowadays. Being the number one item is proper placement IMO.
Go is fantastic and makes it easy to build. Hugo is great too - I'm currently using the Docsy template to avoid/replace multiple software products for a crypto/blockchain project.
I don’t know if writing software as an incidental expense to efficiently allocate capital is actually worse than writing software as an incidental expense to conduct mass surveillance to trick old and poor people into clicking ads.
It's not intellectually honest to weigh Google's worst actions (like tricking poor people into clicking on ads, when they would obviously much rather trick rich people to click on ads) without also weighing their contributions to the world, of which the hedge fund has none.
spf13, congratulations on your move and thank you for what you’ve already done. Was a really cool experience watching your live interview during the recent HugoConf 2022 event.
On the flip side, I didnt realize background clip was now available in all mainstream browsers. I am surprised it is not more common in websites. I might use it in titles or captions but maybe not in something that is inline and so frequent.
Read the guidelines. This is an unproductive useless comment which isn't encouraged in HN.
Also, others buddy! Others care. He didn't submit this. Others who follow his work did. I just knew this alias "spf13" until today. Not the person or his whereabouts. I run my website with Hugo. So while I didn't care before, NOW I DO! This is how you learn about new stuff. If you don't want, just move on from HN!
Why is this kind of unproductive comments cropping up again and again? Haven't these folks read HN guidelines? If you don't care, move on! Why comment anything at all?
1. Functional operators like map/filter/reduce - all of these would be optional but would save SO many lines of code.
2. Add simple conveniences - e.g. "contains" to check if a key is present in a map. Again those who don't want to use these, don't have to.
3. Error handling boilerplate - something to the tune of "?" operator in Rust