26 ms·
I like the sentiment of this article. It's a great analogy. Might be a little off topic, but it reminds me how I am happy that the Go programming language and
by serial_dev 6y ago
I like the sentiment of this article. It's a great analogy.
Might be a little off topic, but it reminds me how I am happy that the Go programming language and its philosophies gained popularity even though I don't use the language regularly. Watching Go talks made me appreciate simplicity and clarity.
It made me accept that I don't always need to use every design pattern in the book. It made me think about the readers of my code, who might not always be experienced enough, or might not always have time to understand the brilliant architecture I came up with. I can have some repeated code sprinkled around in the codebase. I don't always need to have n+1 layers in my architecture where all the layers just call the next layer anyway. It might be better to use functions over a complicated hierarchy of classes. It made me appreciate simple tools and widely accepted conventions that result in codebases that feel familiar the second you dive in.
Of course, go is not the only community where these ideas are prevalent, and it's good to know your design patterns and architecture, etc... Finding the balance is not always easy, but it's good to have a popular, successful "counter force" community.
- brundolf 6y agoI take issue with some of the decisions that went into Go, but I definitely respect the overarching philosophy of keeping things simple and not giving teams enough rope to hang themselves with
- michaelcampbell 6y agoInstead you only give them string, so if they want a rope, for any reason, they have to make it themselves. Every time.
- bitexploder 6y agoAs I get older my code gets a little more verbose and a little less idiomatic to the language I am writing. I’ve been writing code, starting with C, since 95. Mostly Python these days, but I try to make it clear and easy read. Mostly for myself. Future me is always happy when I take the time to comment my overarching goals for a piece of code and make it clean and well composed with enough, but not too many, functions.
- nomel 6y ago> well composed with enough, but too many, functions. In my experience, code with too many functions is more difficult to grok than spaghetti code. It's like trying to read a book with each sentence reference a different page. So, I try to code like I would write, in digestible chunks. > As I get older my code gets a little more verbose I've seen too many of my previous projects die right when I moved on. Now I tend to write code as if it were written by a beginner: verbose and boring, with no magic.
- axcdnt 6y agoSo many levels of indirection is the recipe for the modern goto.
- nx7487 6y ago> In my experience, code with too many functions is more difficult to grok than spaghetti code. In a way, it kind of _is_ spaghetti code. Even if there's no back references, it turns a single train of thought into a string of entrances and exits.
- agallant 6y agoThe best label I've heard for the excessive layers anti-pattern is "lasagna code."
- UK-Al05 6y agoLasagna code isn't meant to be derogatory, just a description.
- agallant 6y agohttps://wiki.c2.com/?LasagnaCode https://wiki.c2.com/?LasagnaCode https://en.wikipedia.org/wiki/Spaghetti_code#Lasagna_code https://en.wikipedia.org/wiki/Spaghetti_code#Lasagna_code https://matthiasnoback.nl/2018/02/lasagna-code-too-many-layers/ https://matthiasnoback.nl/2018/02/lasagna-code-too-many-laye... https://dev.to/mortoray/what-is-your-tale-of-lasagne-code-code-with-too-many-layers-3lp2 https://dev.to/mortoray/what-is-your-tale-of-lasagne-code-co... Generally used with a negative connotation. C2 also discusses how the layers can become entangled/stuck with one another and difficult to replace, which seems to fit the metaphor. For describing layered code in a non-negative fashion, just saying "layered (or "modular") seems most typical.
- haolez 6y agoIt's hard to stay simple when the number of users grow. Go will probably not stay simple for much longer (with generics and whatnot). One thing that I don't understand about the ecosystem is the hate towards GOPATH. Why introduce a complex dependency system for a package manager when you can just pin submodules with git and reap the same benefits? :)
- djur 6y agoHow does pinning submodules give you the same benefits as a package manager?
- kccqzy 6y agoGOPATH is hated because it's poorly thought-out. It's poorly thought-out because Go is designed by Google, who uses Bazel for dependency management. GOPATH is only there because you can't expect everyone to adopt Bazel in order to adopt Go, so some half-assed solution gets designed to get the language out the door. In simpler terms, the people who designed the language don't use GOPATH at all. That's why it's terrible.
- kortex 6y agoI don't think GOPATH is poorly thought out at all. Dependency-environment-locating is a PITA. Off the top of my head, I can't think of a single package management system that doesn't use universal installs, FOO_PATH or "giant local dump per project". Universal: - apt, yum, brew Team PATH: - GOPATH - CMAKE_PREFIX_PATH - PYTHONPATH (which Conda, virtualenv, etc modify) - CARGO_HOME Team redundant local blob: - Node - pipenv Rust is probably the least-half-assed (most full-assed?) model, with both a sane user-wide default for cache (~/.local/cargo), a way to edit that default, and project location flexibility. But I actually love the Go notation that I've opted to organize most of my code around the ~/namespace/src/domain/repo scheme. I never lose track of where a folder is :)
- mssundaram 6y ago> 've opted to organize most of my code around the ~/namespace/src/domain/repo scheme. I never lose track of where a folder is Yes I do the same! I don't lately write any Go but I really appreciate the organization this way
- momokoko 6y ago>I don't always need to have n+1 layers in my architecture where all the layers just call the next layer anyway. This is by far the most common thing I’ve seen consistently in especially difficult to maintain codebases. Anecdotal for sure, but number 2 on that list is way behind. Extra abstractions for a future that has yet to happen and abstractions because the IDE makes it easy to click through the layers is the number 1 by far reason I’ve seen code based be very difficult to maintain. If you just keep in your head, “Can I see exactly enough on this page to know what it does? Not more, not less?“ It’s an impossible ideal but that concept is a fantastic mental guideline for maintainable codebases.
- abledon 6y ago> Can I see exactly enough on this page to know what it does? Not more, not less Is there some book/website/SO post that tries to drive this piont home? Bascialyl some web resource I can link to other programmers to explain the value of coding as such.
- _underfl0w_ 6y agoThis article is from a personal blog on a website with a URL $someguysname.ninja. Maybe you should be the one to write the article you seek! Believe in yourself. If you find yourself with steadfast values that you find tedious to repeatedly communicate, but that you thinks others ought to know about, why not write them down? Who knows - if it's good and resonates with others, is sounds advice, etc. one day it may end up on HN too. Not everything worth doing has already been done before!
- monocasa 6y agoHard same. The best organizational level technique I've found so far is to add the rule of three to code review checklists. An abstraction requires at least three users. Not three callsites, but three distinct clients with different requirements of the abstraction. Obviously it's not a hard rule, and we allow someone to give a reason why they think that it's still a good idea, but forcing a conversation starting with "why is this even necessary" I feel has been a great addition.
- Abishek_Muthian 6y agoThe bold utilitarian approach of Go might face some valid criticisms from seasoned programmers, I myself had to empty my cup(mostly Java) to get onboard Go and I'm glad that I did. After a spine surgery my programming time got severely limited and so I decided to code my future projects with utility focused languages. I had used Python in the past, but the performance tuning once the application scales is counterproductive and expensive to say the least. I wanted a language which has predictable performance, decent standard library and most importantly not waste my time; time I can focus on my health. Go was the answer, even if it meant that I had to let go of some of my decade long programming patterns and practices. Now my only wish w.r.t to Go's future is for it to stick with its utilitarian philosophy and not succumb to pressure of including features which might compromise it and leading to the several forks of Go.
- GordonS 6y agoHow do you feel about coding without generics now, and what do you think about Go's ambition to add them? I'm coming from a C# mindset and thinking of learning Go, but I'm so used to generics...
- Abishek_Muthian 6y agoThat's what I meant when I said that I had to empty my cup and It's unnecessary for most if they're happy with their current language. As for the inclusion of Generics I'm divided, I'm eager to use generics again in my current Go to language but on the other hand I'm worried if this is the direction Go language design team is going to take then where will it end?
- njanirudh 6y agoUnfortunately modern coding interview and general culture has made it a "technical know how d measuring contest". I have seen juniors use all data structures and design patterns regardless of it actually fits correctly or not
- atoav 6y agoI think functions are a good enough abstraction for many things. A few years ago I tended to make everything a class in Python. Nowadays I rarely need more than functions. Learning Rust made me realize just how arbitrary my aesthetical ideas about code where. When I tried to go the class based object oriented route in Rust it failed spectacularly because I was unable to navigate the maze of ownership in no time. Once I let go of these ideas everything became incredibly straightforward. The spell has been broken. That being said I think module borders have become more important to me. Keep seperated what is meant to be seperated.
- rualca 6y ago>>It made me think about the readers of my code (...) I don't always need to have n+1 layers in my architecture where all the layers just call the next layer anyway. Your assertion doesn't make sense. N-tier architectures are primarily intended by the needs of said reader of the code, because it provides a clear understanding of how the overall code is organized. More importantly, it provides a clear idea of what code is expected to call which code, and makes it clear that dependencies only go one way. I have no idea what leads people to believe that ad-hoc solutions improvised on the spot are helpful to the reader instead of clear architectures where all the responsibilities and relationships are lined up clearly from the start.
- rpedela 6y agoIn practice, it rarely turns out that way. I have to deal with large, mature Java codebases for some of my work. The good thing is that the code does just about everything well and rarely breaks. The downside is that when something does break, and I have to debug the code. At some point in the Java world, best practice became building abstraction on top of abstraction on top of abstraction. And often these abstractions just call the next abstraction. Well that makes finding the offending line of code extremely difficult and time-consuming unless you are an expert of the codebase. Had the exact same code been written with less abstractions, debugging would be a lot easier. I am not against abstractions, but I think they lead to hard to read/debug code when overused. I think they need to be used wisely rather than the default.
- rualca 6y ago> At some point in the Java world, best practice became building abstraction on top of abstraction on top of abstraction. It really doesn't. There is nothing intrinsic to Java that forces developers to needlessly add abstractions. If your codebase has too many unwarranted abstractions to the point it adds a toll to your maintenance, it's up to you to refactor your code into maintainability. And no, n-tier architectures do not add abstractions. They never do. At most, you add an interface to invert the dependencies between outer and inner layers, which does not create an abstraction. Instead they lift the interface that was always there,and ensures that you don't have to touch your inner layers when you need to fix issues in your outer layers.
- edumucelli 6y agoGolang and simplicity in the same sentence does not quite reflects my daily experience. Want a Set? Golang does not have one, create a map[type]boolean instead. Want an Enum? Golang does not have one, create a bunch of constants yourself that are not tied together by a type, or create your own type that won't quite make what an Enum is. If simplicity means feeling like you are programming in the 80's, that is what Golang meant for me with simplicity. Not having basic stuff such as Set and having to workaround with a map of booleans is not simplicity, as you will have to make it turning the code into a more complex blob to represent the same kind of data structure. I could go on and on with the list of things that lack instead of things that are simple. </rant>
- noisy_boy 6y agoI recently had to write some Go code and coming from Java/Scala world, actually the "err != nil" thing didn't bother me as much as I thought it would. In fact I liked the explicitness of error handling. However, lack of enums really puzzled me; how is having to go through "iota" hoops simpler than "enum Name { ... choices ... }"? I did like the batteries included approach though - I could build the entire component purely using standard library - not having to deal with importing requests and creating virtualenv etc was refreshing.
- throwaway34241 6y agoFWIW the set equivalent in Go would be map[Thing]struct{}, you don’t need a bool map value. That being said I’m looking forward to more collection types now that they have a plan for generics.
- nickbauman 6y agoThis can be summarized as "It's better to repeat yourself than use the wrong abstraction." It happens often in the attempt to be DRY we add a parameter or some condition to handle a new variation to what seems like a universal logical construct in the code. Do this enough times and the code is no longer comprehensible to any of the people who wrote each variation, let alone a newcommer. We mistake some commonalities with a universality. We become zealots.