32 ms·
Not disagreeing with the sentiment, but I dislike the word "simple" used to describe languages, because it has two meanings: simple = "consists of few parts" an
by pornel 7y ago
Not disagreeing with the sentiment, but I dislike the word "simple" used to describe languages, because it has two meanings: simple = "consists of few parts" and simple = "easy to use", and these are not the same.
Certain things in Go are not easy (not simple), because Go has few language features (is simple).
Go has definitely a lower barrier to entry and is very productive for certain size and complexity of a project. However, as you start pushing beyond "scale" Go is designed for, Go becomes less simple to use. To appreciate things like generics, non-nullable types, no shared mutable state, you have to be working on a problem that requires these things, and only then these extra features pay off and make development and maintenance easier.
- walkingolof 7y ago>However, as you start pushing beyond "scale" Go is designed for, Go becomes less simple to use. I wonder if that is really true, some really complex systems are written in Go and it does seem to scale well with that. Take Kubernetes for example.
- asdkhadsj 7y ago> Certain things in Go are not easy (not simple), because Go has few language features (is simple). Too true, I touch on that in a post I made here as well. In Go I often found myself having to reuse logic in functions that, in Rust, could be hidden behind iterators or custom iterator implementations. While the Rust version is definitely more complex if you look at the implementation of the iterator; in practice you are just using the iterator - and that ends up meaning the problem you're solving keeps locality, and is easier to reason about. In my experience, at least.
- PyroLagus 7y agoI wonder if it is actually more complex. Emergent complexity is a thing, and one only needs to look at Go (the game; pun definitely (not) intended). The rules are dead-simple; you can learn them in under a minute. But to actually play the game well, you have to learn a lot more. You have to memorize openings, learn to identify and utilize patterns, etc. There is a lot of "meta-play" going on, and you could say that high-level Go play is full of abstractions. In fact, you won't have a chance without the abstractions. If you only see individual stones rather than shapes, you're done for. I think the same applies to languages like Go. You don't have generics, but if you want to effectively re-use code, you need abstractions. The difference now is that in languages like Rust, you have predefined and marked abstractions, while in Go, you define them yourself and need to recognize them yourself. Granted, Go also makes certain kinds of abstractions difficult or impossible to manually define within the language, so you may end up with copy-pasted code, but I imagine even that will be manually abstracted through naming and such. The Rust iterator is a pretty simple abstraction in my opinion. It's essentially a lazy list. You see an iterator used, you know what you're getting. You see the map function used, you know it's the same as a for loop over all the elements. A fold/reduce is just a for loop over all elements with a result variable that gets returned. I really don't think using iterators is any more complex than a for loop, and with a for loop, you actually have to look through it to identify the pattern used and find out what it does. I'd say having to manually check for patterns is more work, but I couldn't say which one is more complex; maybe neither is.
- kjksf 7y agoYou can encapsulate iteration logic in Go. I do it in my libraries when warranted. The pattern is: v := NewIteratedValue() for v.Next() { item := v.Item // process item } if v.Err() != nil { // process error } A variation of this pattern exists in standard library and third part libraries. I know that you meant implementing some sort of iteration protocol natively supported by the language, so that you can write: for v { ... } vs: for v.Next() { } But you ended up making much stronger and untrue claim that one can't write re-usable iteration logic in Go.
- atombender 7y ago
- MuffinFlavored 7y agoCan somebody post an example of when you would use generics to solve a problem in the real world, and how that would be implemented in Go instead?
- nine_k 7y agoYou can solve any problem in a language without generics, such as Go, C, Fortran-IV, or any other Turing-complete language, including the Turing machine "assembly". The difference is in speed of producing such code, amount of bugs introduced, ability to understand, modify, and evolve the code, etc.
- takeda 7y agoDon't know Fortran, but while C doesn't have generics you're getting similar behavior due to macros (for example min(), max() are macros) and weak typing. So the need of having generics there is much weaker.
- fwip 7y agoThere are a number of tools (and the "go generate" construct) designed to support code generation. If you just want macro-level behavior, that's easy to do.
- takeda 7y agoYes, and that's what I'm currently doing, but it is essentially just automating writing the same code multiple times. It still has issues, like having to remember to regenerate the code on change, or making harder to use IDE features to refactor. There are also some limitations it has.
- nine_k 7y ago> automating writing the same code multiple times What would you call a language that forces you to write / use a preprocessor to introduce higher-level features? Low-level. More specifically, low-level for the domain where you're working. C is admittedly low-level because it had to be minimal even for 1970 and close to the metal. Other languages usually enjoy less drastic design constraints.
- kristoff_it 7y agoWhenever I used the word `simple` I did it not to mean easy. You raise a good point and I agree that simplicity != ease. I think it's a well known point of discussion from rob pike and, although less authoritative, it's also the focus of my first ever blog post [1] :) That said, I wanted to talk about Go for enterprise development, and I did explicitly made the point that some abstractions are in my opinion detrimental to the reality of enterprise software, and I suspect generics might be one of them. It's a big topic and I honestly don't know the definitive answer, but I just wanted to point that out. I do agree that non-nullable types are good and a big hole in Go's repertoire. [1] https://kristoff.it/blog/simple-not-just-easy/ https://kristoff.it/blog/simple-not-just-easy/
- KirinDave 7y agoHave you gone back and read that post you linked recently? It seems to me like the final section has a lot of bad things to say about the methodlogy of a go developer. Huge, bloated toolchains required to make progress. Code volume rather than appropriate abstraction. To me, your MS Word vs LaTeX graph sure seems like it's damning "easy" languages like Golang in favor of other languages with more powerful abstractions. You also assert that Golang is easier to learn than other languages. I don't think you've really got a leg to stand on there. It's "easy" for folks doing service development because the arbitrary decisions made by Golang were made from the perspective of someone experienced at writing web services. If you already know C and Python a bit, Golang cherrypicks a lot of good stuff, but if you don't (or you're not writing a bunch of web services that essentially do nothing but punt to C frameworks and validate strings in request headers) then Go's going to struggle, and folks have pointed this out. It's pretty surprising to me that you write about how Generics are the death of enterprise software when so much quite-usable software uses generics. Why do yo simply get to forget the existence of the huge body of Java work and instead assert it's bad? Android uses generics in many cases where appropriate and it's one of the better UI kids available these days. Even the Actor methodology you're citing as part of Golang as good is actually a fairly sophisticated abstraction with lots of implications for the runtime and execution order. Why is that specific programming abstraction given a pass because of its benefits, but writing a generic linked list is going to be the death of your programming organization? You also defend the structuring of many enterprise groups even as you suggest that they lack training, refuse to pay technical debt, and place unreasonable burdens on developers. You seem to have just accepted this and said Golang helps you be more complicit in this mode of operation that you also seem to suggest is somewhat bad. Why would we want to pander to a methodology that asks junior developers to proceed without training and places focus on process and hyper-specialized domain experts rather than clear communication, sound architecture and sustainable velocity? I'm quite confused how you can hold both these opinions at the same time. It seems like they're contradictory.
- larusso 7y agoRich Hockey made a nice talk about this. https://youtu.be/34_L7t7fD_U https://youtu.be/34_L7t7fD_U
- dunk010 7y agoYup. This is the origin of this idea.
- iwintermute 7y agohe also had another talk https://www.infoq.com/presentations/Design-Composition-Performance/ https://www.infoq.com/presentations/Design-Composition-Perfo... and I would argue there's idea that simplicity of the instrument/tool is not a problem in itself and we shouldn't lose it in pursuit of 'ease'
- munificent 7y agoAuto-complete turning his name into "Rick Hockey" does actually explain what's been going on with Rich's hair over the past few years.
- larusso 7y agoHow stupid of me not to spot this ...
- mbillie1 7y ago> However, as you start pushing beyond "scale" Go is designed for, Go was designed at Google to be used internally at Google, so frankly it's hard to imagine commonly pushing past the "scale" Go was designed for.
- elsurudo 7y agoI assume the GP meant "scale of codebase complexity" – which is orthogonal to whether something is "web scale" (ie. everything Google does).
- creyes 7y agoIsn't the Google codebase infamously a monorepo with billions of loc? That seems like it fits "scale of codebase complexity" as well as "web scale"
- jcranmer 7y agoYes, but much (if not most) of that codebase is in C++.
- munificent 7y agoIt's a monolithic repo, but not a monolithic codebase. It contains many many separate projects, libraries, and applications. There's a lot of code reuse, but it's not like you have to wrap your head around the whole thing.
- jimbokun 7y agoHow do you check out a project like that?
- deleted 7y ago[deleted]
- CaptainJustin 7y agoPeople may also mean different things by scale. For me, scale means more micro-services. For another person it means a bigger monolith.
- lostjohnny 7y ago> However, as you start pushing beyond "scale" Go is designed for Like Google scale? That's what Go is designed for.
- pjmlp 7y agoYes, that is why Google mostly uses Java and C++ instead.
- geodel 7y agoOr it may be because Java and C++ are much older so lot more code is written in those. And companies do not replace working code just because new language developed in house has few more features.
- pjmlp 7y agoExcept that lots of new code also get written in those languages. Google's major Go projects appear to be gVisor, Android GPGPU debugger, Fucshia's TCP/IP stack and volume management tools and the download server as it was done by the Go team. https://commandcenter.blogspot.com/2012/06/less-is-exponentially-more.html https://commandcenter.blogspot.com/2012/06/less-is-exponenti...
- xxxpupugo 7y agoYou forgot kubernetes
- pjmlp 7y agoI did indeed. https://archive.fosdem.org/2019/schedule/event/kubernetesclusterfuck/ https://archive.fosdem.org/2019/schedule/event/kubernetesclu...
- geodel 7y agoFrom description: "In this talk we explore the devastating effects using object oriented antipatterns in go while building programs in a monorepo. ... Unknown to most, Kubernetes was originally written in Java. If you have ever looked at the source code, or vendored a library you probably have already noticed a fair amount of factory patterns and singletons littered throughout the code base. " So basically writing Java in Go lead to clusterfuck codebase.
- slifin 7y agoRich Hickey describes simple as unbraided, like a class is identity, state and schema all braided together And easy as close by and accessible i.e. npm i latest-framework might be easy but not simple https://www.infoq.com/presentations/Simple-Made-Easy/ https://www.infoq.com/presentations/Simple-Made-Easy/
- setr 7y agoisn't the same idea exactly covered by the term "(de)coupled"?
- modwest 7y agoIt can include decoupling, but no it's not synonymous.
- modwest 7y agoThis presentation had an outsize influence on my professional development as a programmer. If I've watched it once (and I have), I've watched it a dozen times. edit: The "Limits" slide (go to 12:30 in the vid) is one that I really internalized early on. And looking at it again years later, the principles from that slide absolutely guide my app development: - We can only hope to make reliable those things we can understand - We can only consider a few things at a time - Intertwined things must be considered together - Complexity undermines understanding
- melling 7y ago“non-nullable types“ This is not some advanced feature. I would think this should be the default in any language.
- crimsonalucard 7y agoAll the popular languages from last gen, did not have non-nullable types.
- jerf 7y agoWe're accustomed to thinking of our world as really fast moving with constant technology turnover, but computer programming languages turn over at maybe twice the speed of human generations. A lot of the features that HN posters, including me, simply can't imagine a language without have yet to penetrate the top ten list of current programming languages at all. My point isn't that this is wrong, but just to suggest that people's mental models incorporate the idea that programming languages actually move pretty slowly. There's a constant froth of undergrowth in the forest, but it takes a long time to establish a tree, and a long time for it to be supplanted by another.
- TheCoelacanth 7y agoAnd it was a mistake in all of them.
- crimsonalucard 7y ago"I call it my billion-dollar mistake…At that time, I was designing the first comprehensive type system for references in an object-oriented language. My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn’t resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years." – Tony Hoare, inventor of ALGOL W.
- takeda 7y agoGood point, actually C is perfect example of this, it is a actually quite simple language that is not that simple to use.
- mlindner 7y agoThe tasks you do with any language are often not simple. And the simpler the language you use the more complex and harder the task gets. Assembly language is "simple" in the extreme but getting a task done in it is not trivial.
- littlestymaar 7y agoA good example of that is the difference of allocation handling in both languages: Go is simpler than Rust because in Go everything is automatic, while in Rust there is an explicit Box if you want to allocate on the heap. But avoiding heap allocation is easier in Rust than in Go because of the explicitness vs automatic management.
- social_quotient 7y agore: Simple So it took me a number of years running a tech agency to realize that the words "simple" and “easy” are bad. In my job I now correct my, and our project managers, from using the word "simple" to the word "straightforward". I find that the term simple connotes a feeling of the task/work being easy and thereby quick to get done. As an agency the term “simple” speaks not only to risk and ease of completion but also budget, as a function of time. Moving 10,000 bricks from point A to B is likely simple or easy, but it takes time. If not careful a client can think “oh it’s just moving 10K bricks 5 feet over, they should automagically be able to do this since John said it was “simple” ”. What I intended to impart was that I know how to do it, no solutioning needed, we have the skills and resources to get it done, and we can probably get moving on this quickly. Now I say something more like … “Moving 10,000 bricks from A to B is straightforward for my team, when do you want us to get started”.
- arhyth 7y agokind of agree but also disagree. the runway for Go to go (pun unintended) from easy to difficult to use because of it consisting few parts is far longer than for a developer using a feature rich language to eventually shoot themselves in the foot. let me throw in another language in the mix to describe what i personally think is _almost_ the best tradeoff between this difficult and easy simplicity. Elixir. it has almost the same amount of keywords (as a proxy measure to API surface) as Go but on the other hand it also exposes metaprogramming and so, if you really want to, you can easily shoot yourself in the foot. but in both languages, as I said for Go, the runway for language usability to go from easy to difficult due to their limited features is very very long.
- ospider 7y agoGo can not be simple, because software itself is a complex beast, language really does not matter. One thing that gophers say a lot is the count of Go's keywords is minimal. This is true literally, only 25 keywords as of Go 1.13. But it does not reduce the complexity of writing code, it just hides them. For example, Go does not have the `new` keyword, but it has `make` function, which is so powerful that one of my friends actually thought `make` was a keyword of Go.