[HN Gopher] The ecosystem of the Go programming language
___________________________________________________________________
The ecosystem of the Go programming language
Author : henvic
Score : 179 points
Date : 2021-03-22 12:55 UTC (10 hours ago)
(HTM) web link (henvic.dev)
(TXT) w3m dump (henvic.dev)
| CobrastanJorji wrote:
| This is a great article, but it felt needlessly defensive on the
| "lack of assertions" thing. Admitting that something is missing
| makes the rest of the article feel more believable. No need to
| say stuff like "maybe the lack of asserts makes the test code
| build faster so it's actually a good thing." Just say
| "unfortunately, no asserts."
| petercooper wrote:
| Just as it's not mentioned there, I've been running a Go
| newsletter for the past six years at https://golangweekly.com/
| (yes, RSS is available) - the archive can act a sort of week by
| week "what happened" for anyone looking back to specific points
| in Go's history over that time.
| donut wrote:
| Hey Peter! Thank you for doing this. I'm a regular reader and
| love what you do.
| petercooper wrote:
| Thanks, very kind! :)
| henvic wrote:
| omg, I can't believe I forgot to add it!
|
| Just added :)
| petercooper wrote:
| Thanks, no problem! Congratulations on the success of your
| post!
| grossemerde wrote:
| Cdjksnbhhfsbdvfsdbhjgeographiedemerdequifaitchierdansleculc
| ommeunchevaldemerde Kek
| irokita94 wrote:
| I see that the technology world got in love with GoLang lately.
| In the Software House I work we get tons of questions, can we
| build an app in Go (yes, we can).
|
| Is this the Google authority that gets people so eager, to use
| this specific programming language? And I'm talking about
| entrepreneurs who know ZERO about app development - yet, they
| insist to develop their app in Go. Even though most of the time,
| it would be easier for us to do it in Ruby on Rails we agree to
| do it in GO. Is this the trust matter of why GO has got such a
| great PR lately?
|
| Nevertheless, dear developers: learn it, because from the
| business side I see its potential may only rising as it did with
| other backed by huge corporations languages (Flutter, React
| Native).
|
| PS. Interested in GO benefits written from the business
| perspective? Check them here: https://blog.railwaymen.org/why-
| use-golang-to-build-your-bus...
| toolz wrote:
| I was writing code in go for maybe a week before I noticed "make"
| was an overloaded function and subsequently noticing go doesn't
| allow you to overload your own functions.
|
| Things as simple as this seem mundane, but it's painfully obvious
| discrepancies like this that make me avoid go when I can - if I'm
| going to utilize a new language, I'd prefer it to have
| interesting and consistent paradigms that lead developers to a
| similar understanding of how to use the language. Inconsistency
| in the core language like this doesn't give me a lot of hope for
| the longevity of go projects remaining easy to reason about.
| yulaow wrote:
| Is this updated? I see in the suggested resources to learn Go
| there is a book created in 2015... The language and related
| patterns changed so little that that book is still good?
|
| Or anyway, do you have any to suggest?
| q3k wrote:
| > The language and related pattern changed so little that that
| book is still good?
|
| Pretty much yes, and TGPL/Effective Go are still very good
| resources to learn the language, if not still the best
| available.
|
| Probably the biggest changes since 2015 were constant stdlib
| improvements / extensions, and things like the context API
| becoming standardized across the ecosystem. Oh, and Go modules.
| Otherwise the language is pretty much unchanged.
| petercooper wrote:
| If you mean _The Go Programming Language_ then yes, it 's still
| a fine book. It doesn't cover new additions like Go modules, of
| course, but in terms of the core elements of the language, it
| stands up well. Are you going to probably want more once you've
| covered the essentials? Yes, but it'll put you in a great
| position to take on further material.
| wbl wrote:
| I still use my K&R which proudly proclaims that it includes the
| new ANSI C 89.
| Ashanmaril wrote:
| I've been using Go for a personal project of mine recently. I had
| briefly used it at the tail end of my internship while getting my
| degree, but nothing particularly in-depth, and it was some pretty
| simple server code that never really challenged me.
|
| There's definitely some nice stuff about it, but there's also
| some stuff that's a bit of a pain. For one thing, being straight
| up unable to compile a program if there's an unused variable, not
| even a debug compiler flag or anything to allow it while testing.
| There's a lot of cases where I just want to move one thing
| around, or I'm partway through writing a function and just want
| to see what state something is in at a point, so I want to throw
| a breakpoint on a line and run the program up to that point. But
| even though my code is technically all valid, because the
| variable I want to look at is unused, or I commented out a line
| that makes something else unused, I now can't compile at all. So
| there's a lot of times I'll have to throw in a random fmt.Print
| of a random property of index zero of an array or something,
| which might crash anyway if it's reached, but at least it'll
| compile. It maybe doesn't seem like it would be that big of a
| deal, but when you've got a train of thought going, and you're
| trying to iterate fast, it can really pull you out of the flow of
| things.
|
| There's also a lot of weird situations where I find it hard to
| keep things clean. For instance, I like using this shorthand:
| if err := doThing(bar); err != nil { // handle error
| }
|
| But if you're doing it in a case where your function returns a
| result and an error, i.e. if foo, err :=
| doThing(bar); err != nil { // handle error }
|
| That's indeed valid code, but foo only exists in the scope of
| that error handling. So you'd have to declare it above with its
| type var foo FooType if foo, err :=
| doThing(bar); err != nil { // handle error }
|
| But you can't actually do this because when using type inference,
| both return values have to not be declared beforehand. So you
| have to pull err out into a declared var with a type, and remove
| the type inference altogether like this var foo
| FooType var err Error if foo, err = doThing(bar); err
| != nil { // handle error }
|
| And from that point on, if you're using this pattern again
| anywhere else below in that function and you want to continue
| using that slick error handling shorthand, there's barely any
| point because err already exists in your scope, and you'd just be
| redeclaring it.
|
| Perhaps there's some tricks I don't know about, but I tend to run
| into situations like this a lot, and I spend so much time trying
| to appease weird edge-cases of the compiler's strict rules that
| is really throws a wrench in my workflow.
| jodoherty wrote:
| I always fall back on this pattern when the return values need
| to be used further down: foo, err :=
| doThing(bar) if err != nil { // handle error
| } foo2, err := doThing(bar) if err != nil {
| // handle error }
|
| Only one value in a multi-valued assignment has to be
| undeclared to use the short variable declaration operator (:=).
| If the variable already exists in the current scope and the
| type matches, it will get reused.
|
| https://play.golang.org/p/qo141lT-Jjp
| Ashanmaril wrote:
| >If the variable already exists in the current scope and the
| type matches, it will get reused.
|
| That's good to know. I suppose that would probably be the
| cleanest way of doing it. Thank you!
| spyspy wrote:
| I've been a professional Go developer since 2015 and I prefer
| to never use the shorthand. Saving a single line is never worth
| how much harder it is to read.
| cratermoon wrote:
| Well, you just pointed out why the shorthand is only
| stylistically correct for functions that only have an error
| return. Trying to force a convention into a completely
| different situation is going to cause pain in any language.
| bbkane wrote:
| To "use" unused variables, I pass them to the following
| function: // PretendToUse is an empty
| function to shut up the Go compiler while prototyping
| func PretendToUse(args ...interface{}) {}
| PretendToUs(var1, var2)
| sethammons wrote:
| A workaround: assign the unused variable to underscore.
| _ = myUnusedVar
|
| Now you have used it.
| Ashanmaril wrote:
| That's smart, I never thought of that. Thanks!
| jimmyed wrote:
| I have a modified go compiler which ignores the unused
| variable rule. If you are interested, I can share it with
| you.
| q3k wrote:
| Just do foo, err := doThing(bar) if
| err != nil { // ... }
|
| and carry on with your life. Go is not a language in which you
| obsess over small things like these.
| isaiahg wrote:
| I was thinking that as I was reading. Its 1 extra new line,
| and arguably more readable.
| dunefox wrote:
| So Go is a language that values the compiler writer over the
| programmer?
| youerbt wrote:
| The corporation over the programmer.
| fredrikholm wrote:
| The difference between those two blocks is that a semi-
| colon was replaced with a new line.
|
| _How insulting_.
| unionpivo wrote:
| It's very opiniated language.
|
| And to be fair, I prefer to do this in 2 lines, since it's
| simpler to read (less going on in each line.)
| mweibel wrote:
| you could use an `else` clause for the scope:
| if foo, err := doThing(bar); err != nil { // handle
| error } else { // handle foo }
|
| but most don't use that form and just do the call outside:
| foo, err := doThing(bar) if err != nil { //
| handle error }
| cratermoon wrote:
| or pass doThing as a function parameter
|
| https://play.golang.org/p/4PoK6EZc4W9
| lawrenceyan wrote:
| Ken Thompson states that, initially, Go was purely an
| experimental project. Referring to himself along with the other
| original authors of Go, he states:
|
| > When the three of us [Thompson, Rob Pike, and Robert Griesemer]
| got started, it was pure research. The three of us got together
| and decided that we hated C++. [laughter] ... [Returning to Go,]
| we started off with the idea that all three of us had to be
| talked into every feature in the language, so there was no
| extraneous garbage put into the language for any reason.
| isaiahg wrote:
| I really like go. Its simple in that you can learn the language
| pretty quick. I might get burned in another comment below but
| it's the language that feels the closest to C to me. Both are
| really simple languages that can get relatively complicated
| pretty fast. Inheritance through embedding for one feels a lot
| like using -fms-extensions in C.
|
| However I think the coolest part of the language is the part no
| one talks about. The inclusion of comments as a major part of a
| program.
|
| // +linux
|
| for managing files for specific platforms is just wonderful.
|
| //go:embed
|
| for embedding files and directories into your program
|
| // #include <stdlib.h> import "C"
|
| is probably the coolest and easiest ways to use C libraries I've
| seen. You can write C code directly into your go files and even
| set complier and linker flags.
|
| //go:generate
|
| can allow you to automate your build process from within your
| codebase.
| avaldeso wrote:
| > // #include <stdlib.h> import "C"
|
| > is probably the coolest and easiest ways to use C libraries
| I've seen.
|
| You should see Zig's interoperability.
| everybodyknows wrote:
| Documentation links (incomplete): // +linux
|
| Dunno -- help, anyone? //go:embed
|
| https://golang.org/pkg/embed/ // #include
| <stdlib.h> import "C"
|
| https://golang.org/cmd/cgo/ // go:generate
|
| https://golang.org/cmd/go/#hdr-Generate_Go_files_by_processi...
| ainar-g wrote:
| > Dunno -- help, anyone?
|
| https://golang.org/cmd/go/#hdr-Build_constraints
|
| EDIT: Those are in the process of being replaced with
| //go:build directives. See
| https://github.com/golang/go/issues/41184.
| JeremyBanks wrote:
| Go: we have so few keywords! Simple language!
|
| Also Go: because we shoved them all into comments instead!
|
| This seems like an extremely weird choice.
| vram22 wrote:
| Yes, I agree. Also (with the big caveat that I am not even a
| little bit of a language designer / implementer / lawyer,
| just a guy interested in these PL topics from early in my
| career), the use of comments, which are meant to be ignored
| by the compiler, to make certain actions happen, seems non-
| orthogonal and not a good choice. Like shoehorning something
| into something else it was not meant to be or support.
| everybodyknows wrote:
| As someone who uses the language every day, I fully agree.
| My work would be easier if they all conformed to some
| syntax not easily mistaken for an ordinary line comment. A
| standard preamble of '///', say.
|
| No doubt sophisticated IDEs highlight them somehow, but
| more naive editor extensions e.g. Emacs 'go-mode', do not.
| No color-coding.
| isaiahg wrote:
| As someone who uses the language. I think it's one of its
| most overlooked features. By convention comments are
| ignored, but the truth is they're not by the programmer.
| Comments are extremely important to keep track of what
| you're doing and reading other people's code. So I think
| this is a case where the convention doesn't meet the
| reality. Also using these features within comments makes it
| so every use of these extra features is documented and
| shows up in completions, so you the programmer always know
| what you're doing. I'm a fan haha
| jimmyed wrote:
| I remember Rob Pike talking about how each language has its own
| way of doing things and it's bad to keep adding all features to
| all languages. This only makes them all end up being the same he
| said.
|
| The Go way was code generation. After they included generics, I
| wonder if the go team has let go of that principle.
| pansa2 wrote:
| Here's a quote from Rob Pike (in 2015) about what Go was trying
| to avoid:
|
| "Java, JavaScript (ECMAScript), Typescript, C#, C++, Hack
| (PHP), and more [...] actively borrow features from one
| another. They are converging into a single huge language."
|
| https://www.dotconferences.com/2015/11/rob-pike-simplicity-i...
| jayd16 wrote:
| Or you could see that languages have use cases, use cases
| overlap, languages should adopt useful tools for their use
| cases, therefore languages will often adopt the same tools as
| other languages with overlapping use cases.
| nerdponx wrote:
| It's 2021, the convergence still hasn't happened yet. It's
| never going to happen. I know Rob Pike is probably smarter
| than me, but this a bad hot take in 2015, and it's outright
| stinky in 2021.
| cratermoon wrote:
| They are all similar enough that a programmer fluent in one
| can start writing code _in the style they are familiar
| with_ in another. Remember the old saying, "You can write
| FORTRAN in any language[1]"? Well, with the aforementioned
| set of languages, you can write one of them in another _and
| it doesn 't even look wrong_.
|
| [1] https://blog.codinghorror.com/you-can-write-fortran-in-
| any-l...
| nerdponx wrote:
| _They are all similar enough that a programmer fluent in
| one can start writing code in the style they are familiar
| with in another ... with the aforementioned set of
| languages, you can write one of them in another and it
| doesn 't even look wrong._
|
| 1. Only superficially, because they all share the same
| basic flow-control constructs and (except for Python) the
| same C-inspired syntax. They all have totally different
| standard libraries, package ecosystems, etc.
|
| 2. I don't see what makes Go exempt, other than "wow
| great they didn't add generics bless the Go core team."
| cratermoon wrote:
| Go was built as a language to make communicating
| sequential processes[1] first-class citizens. Thus the
| ubiquity of channels and goroutines. No locks, no
| condition variables, no callbacks[2]. Writing a bunch of
| code using locks and callbacks in Go goes against the
| grain of the language.
|
| [1]https://www.cs.cmu.edu/~crary/819-f09/Hoare78.pdf
|
| [2]https://www.youtube.com/watch?v=f6kdp27TYZs
| Thaxll wrote:
| Well look at patern matching for example, they're all
| adding that. Isn't that convergence?
|
| https://www.php.net/manual/en/control-structures.match.php
|
| https://www.python.org/dev/peps/pep-0622/
|
| https://www.infoq.com/articles/java-pattern-matching/
|
| https://docs.microsoft.com/en-us/archive/msdn-
| magazine/2019/...
|
| I could go on with various topics, immutability etc ...
| It's pretty clear that in the past 10 years language
| evolved more quickly and borrow concepts from other
| languages.
| nerdponx wrote:
| Languages evolving and borrowing good ideas from each
| other* is not the same thing as hyperbolically sneering
| at some of the most popular programming languages in the
| world because they're supposedly all converging into one
| single language, which they never were doing and never
| will do.
|
| *Note that the new Python pattern matching has a somewhat
| controversial design, and it probably won't see
| significant adoption in the wild for several years, if
| ever.
| avaldeso wrote:
| > Languages evolving and borrowing good ideas from each
| other* is not the same thing as hyperbolically sneering
| at some of the most popular programming languages in the
| world because they're supposedly all converging into one
| single language, which they never were doing and never
| will do.
|
| And yet PHP, Java and C# MVC web apps looks all the same
| in both syntax and structure. Same syntax for interfaces,
| classes, namespaces, entity models, query builders,
| controllers, views and so on. A modern Symfony
| application looks almost the same as a Spring one.
| ozkatz wrote:
| 6 years is not a lot of time if you examine the progress of
| modern programming languages.
|
| These languages are _more_ similar to one another than they
| were 6 years ago. I don 't know if it was meant to be taken
| literally, but I definitely don't think it's "outright
| stinky" to claim convergence.
| thomascgalvin wrote:
| That's not entirely a bad thing.
|
| We've learned a lot about language ergonomics in the past
| forty-nine years. Generics are super useful. Lambdas and
| streams can cut down on a lot of boilerplate. Immutables make
| code easier to reason about.
|
| And I'm glad that I have access to all of those things in
| Java. I'm not upset that my workday language is being
| polluted by outside influences, because I'm not a purist, I'm
| a programmer. I don't care that records were lifted from
| Scala and Kotlin ... I care about how they can make my code
| better.
|
| The idea that we should deprive ourselves of useful features
| because it makes languages too similar makes no sense to me.
| heyparkerj wrote:
| You should watch the talk - I actually happened to do so
| yesterday so it's still in my mind.
|
| The point is not that they're withholding features because
| it makes the language too similar to others, and I'm sure
| that's not what you were really thinking the argument is
| either. The thing they're trying to focus on is that with
| ever increasing amount of features, you have an ever
| increasing amount of complexity added, which has
| implications on the amount of conversations, decisions,
| readability and difficulty your team is going to have when
| tackling any given problem. It can really just be boiled
| down to increasing features past what is needed can be
| considered bloat, which does not come free to a developer
| or team's collective consciousness.
|
| To quote/paraphrase from the 5:10 mark of his talk...
|
| "If a language has too many features, or even more than you
| might need, you spend time programming thinking about which
| features to use... you might even spend half an hour
| messing with a few lines of code to [see how a given
| feature fits into the solution]... [and even more, when you
| revisit that code, you have to get back into the thought
| process you initially went through when determining which
| features to use]."
| thomascgalvin wrote:
| That's certainly fair. I was just talking to someone
| about how it used to be possible to hold the entire Java
| ecosystem in your head at once, but that was probably 15
| years ago.
|
| On the other hand, adding _language_ complexity can
| decrease _program_ complexity a great deal. Generics are
| the prime example of this. If you see List <Foo> and
| List<Bar>, you know exactly how both work. But if you see
| FooList and BarList, you might have to stop and worry
| about how each is individually implemented.
|
| Or the whole "while is spelled for in Go" thing. Sure,
| they managed to strike out one whole keyword from their
| language, but anyone coming from another language is
| going to have a momentary brain skip while they try to
| figure out why that is, and how they need to re-write
| their while loop as a for-loop-but-not.
| jimmyed wrote:
| I was with you till the List<x>, but writing the while
| loop as a for loop is controversial. C'mon man. That is
| second nature for anyone programming for a few weeks.
| streblo wrote:
| > it's bad to keep adding all features to all languages
|
| I understand the reasoning behind this take - a lot of modern
| languages have wound up somewhat bloated, with features that
| are either non-orthogonal to other features and break the 'one
| way to do it' principle (Scala comes to mind), or with features
| that seem tacked-on and feel alien to the language (the latest
| versions of python come to mind). I understand, in theory, why
| go tries to buck this trend.
|
| The problem is that in bucking this trend, go has (at least
| historically) not evolved enough to fix some of its own core
| issues. And it does have some big issues - nils, zero values,
| and non-thread safe primitives come to mind for me. I'm all for
| being thoughtful about introducing changes and making sure
| those changes are idiomatic and don't violate the 'ethos of
| go'. But avoiding making those changes in the name of 'keeping
| it simple' never made sense to me in cases where programmers
| are shooting themselves in the feet and already not having a
| simple time with your language.
| shaan7 wrote:
| Code generation only solved part of the problem - saving the
| trouble of having to write repetitive code. It does not solve
| the maintainability problem because if something needs to
| change then you need to manually change all the generated code.
| I have been using Go since last ~6 years and I'm really excited
| that the only pain point I had with Go will soon go away \o/
| abatilo wrote:
| Wasn't the ability to add a //go:generate comment enough to
| make it easy to re-generate anything that you needed?
| isaiahg wrote:
| Generation is a rather big solution for sometimes small
| problems. For many things like utility functions I think
| generics are much more readable and easier to understand
| while go generate would be heavy handed.
| throwaway189262 wrote:
| Yet Go's code generation is clunky even compared with Java's
| Annotation Processors.
| hu3 wrote:
| Considering how long and how much discussion it took to
| implement generics (coming in 1.18 according to FAQ [1]), I'd
| be inclined to say it supports their principle.
|
| I don't think they ever said they wouldn't implement Generics.
| It was a matter of maturing and consideration of different
| proposals.
|
| [1] https://golang.org/doc/faq#generics
| Thaxll wrote:
| 10 years later the language is still the same, not much has
| changed, I can't say the same about Rust, C#, Java, PHP, Python
| etc ... The only major thing that came in the last couple of
| years was Go module, and it's more on the tooling side than the
| language itself.
| dkarl wrote:
| You can think of generics as providing support for a simple,
| common form of code generation in the language itself. That
| might not be technically precisely correct, but looking at it
| that way makes it seem like not a radical change at all.
| jonathanstrange wrote:
| I like Go and have no major complaints about it. I especially
| like the highly performant garbage collector and the fact that
| there are a lot of libraries for it. With the libraries you have
| to be careful, though, quality of 3rd-party libraries differs a
| lot on Github.
|
| There is also one point of critique, I believe that Go got its
| concurrency primitives wrong. I fear people will hate me for
| saying this, but I say it because almost every library I've
| tested that uses lots of goroutines fails or produces some
| serious concurrency errors at one point or another. Not only are
| there many race conditions in Go code, there are also many
| libraries that silently fail. For example, scan Github for
| parallel directory walkers or check out uses of sync.atomic.
|
| I personally believe that both transactional memory and the actor
| model are easier to use although it might be harder to implement
| and make them efficient. I also think that thread local storage
| and Goroutine identities would have been useful, despite what the
| language purists say. Generally speaking, I think Go's choices of
| concurrency primitives are too low level. (I'm not saying there
| is anything wrong with them per se, just too low-level for most
| of Go's users, and I'm not excluding myself in this assessment.)
| sangnoir wrote:
| Always read the documentation of your libraries to see if they
| give any thread-safety assurances - if they don't mention
| thread-safety, assume they do not have it.
|
| Concurrency in general, is _really_ hard: hard to express and
| hard to debug - none of the languages I know do it perfectly.
| However, I like Go 's concurrency primitives & tooling the
| most. Javascript and Erlang are runners up - for the record,
| the languages I'm familiar with are Erlang, Go, Python, Java,
| Javascript and C. I wouldn't know where C# or Rust would fit.
| dilap wrote:
| Yeah, bounded channels ended up being more effective as a hype
| mechanism than a great concurrency primitive, I would say.
| Coming from Go and kicking the tires a bit on Rust, I was
| impressed w/ how much nicer it was to write parallel code using
| Rust + the crossbeam library than Go.
|
| At the end of the day Go's concurrency story is just
| traditional threads and mutexes, with custom syntax for one
| particular datastructure.
|
| But, you do get a great runtime race detector & the M:N
| scheduler, so you can use lots of goroutines w/o blowing out
| memory, avoiding async hassles.
| coder543 wrote:
| I agree with a lot of this. I'm especially looking forward how
| generics should make it easier to build a library of high level
| concurrency patterns that people can use in Go, instead of
| everyone trying to build their own. Promises (which would allow
| you to start a number of parallel tasks, then wait on the
| results), "parallel for" with controlled amounts of
| concurrency, etc.
|
| The M:N scheduler is great, and the ability to easily spin off
| Goroutines is really nice, but I think most people shouldn't
| need to manually launch goroutines most of the time. Goroutines
| should just be an implementation detail.
| synergy20 wrote:
| Python is also said to be beginner friendly and easy to learn but
| in fact there are a lot tricks hidden somewhere and if you want
| to be a professional python programmer, there are lots to learn
| and they're very deep.
|
| Go is indeed great for web-oriented applications, its built-in
| network stack is really handy, and you don't need run a nginx,
| another application server, etc, everything can be one single
| executable, it's like a docker itself.
| diarrhea wrote:
| Disclaimer: I don't know anything.
|
| > _Python is also said to be beginner friendly and easy to
| learn but in fact there are a lot tricks hidden somewhere and
| if you want to be a professional python programmer, there are
| lots to learn and they 're very deep._
|
| Yeah. I'd add that to become proficient, you are also going to
| have to learn a bit of C and know your way around Python's
| bytecode. You'll have to learn the language _and_ the
| interpreter.
|
| I've never used a compiled language (shame on me), but I'm not
| aware of people _learning_ the Go compiler aside from a couple
| of its options maybe.
|
| The static binary thing is amazing, I love it. By now, a large
| part of my selfhosted stuff is written in Go and all of it is
| great so far (no causality, "just" correlation).
| sdevonoes wrote:
| I find Go the "perfect" programming language except for two
| things:
|
| - the one to one mapping between directories and packages. It
| feels so inflexible compared to what other programming languages
| have (e.g., namespaces)
|
| - that I have to hardcode "github.com" (or another website) in my
| source files. Sure I can do "find and replace" if needed, but
| this kind of stuff shouldn't really be within the `.go` source
| files. Just add a `dependencies.txt` that maps names (used in
| code) to urls. Easy
|
| Having said that, I enjoy writing Go code.
| jimmyed wrote:
| Does Go have tail recursion? I'm guessing not since Go isn't big
| on the "optimization" part.
| cratermoon wrote:
| Depends on what you're optimizing for.
| fredrikholm wrote:
| > Go isn't big on the "optimization" part.
|
| Care to elaborate?
| jerf wrote:
| It's true. Go prioritizes compile speed over a ton of
| optimization. It does fast ones, but it doesn't do the
| expensive ones.
|
| I don't know whether the Go compiler never does tail-call
| optimization, but I do know it is never something you can
| count on.
|
| (There's two kinds of tail call optimization... there's the
| one where the compiler may choose to do it as an optimization
| step, but you can't ever count on it because at any time for
| any reason it may stop, so you have to assume it didn't
| happen. Then there's the kind you can absolutely count on,
| and program tail-call-based algorithms secure in the
| knowledge that they won't blow out the stack. I'm pretty sure
| Go doesn't have the latter.)
| fredrikholm wrote:
| Thank you for clarifying.
|
| Does this apply to procedural code as well? Go not
| implementing TCO makes sense as the language is _very_
| Wirthian.
| monocasa wrote:
| Tail recursion isn't a computationally/memory intensive
| optimization to make, so it's been in since the beginning.
|
| It doesn't guarantee that it will make that optimization
| though, unlike some more functional languages that rely on that
| to generate the same stack consumption as a for loop would.
| thomascgalvin wrote:
| Yes: https://blog.usejournal.com/tail-recursion-in-go-
| fb5cf69a0f2...
| jerf wrote:
| FWIW, I read "tail calls" as referring to the optimization
| that allows you to _rely_ on the tail-recursive calls not
| generating stack frames, on the grounds that I 'm not aware
| of any language that specifically _forbids_ tail recursion.
| mrmister00 wrote:
| Is it me or did Go fail its original mission to replace systems
| languages (c/c++), but then somehow achieved victory by loads of
| Python devs embracing it as a far more performant runtime for
| their code?
|
| Whichever way it is, as a lisper I just find the language tedious
| and ceremonial, and its csp implementation lacking.
| whimsicalism wrote:
| I feel like Go is more similar to another Java or C# in the
| role that it fills in enterprises.
| kaladin_1 wrote:
| Nice article...
|
| Over here I've invested a lot in Java, to be used where static
| typing is necessary, JavaScript (Node.Js), Elixir and PHP on
| other occasions. But it's beginning to look like Go will displace
| Java. So, might be high time we learned Go :/
| thomascgalvin wrote:
| The only production Go code I ever see is in a kubernetes
| operator. The backend services I see deployed are probably 75%
| JVM, 25% Node, and less than 1% something else.
|
| Go is popular at Google, but we're kind of past the point where
| something being popular at Google makes it popular everywhere.
| kyrra wrote:
| (googler, opinions are my own)
|
| Google still has LOTS of C++ and Java. Like most companies,
| we're not going to rewrite large code bases in other
| languages just because its "new" (comparatively). Greenfield
| projects can move to new languages more easily.
| Philip-J-Fry wrote:
| Twitch.tv uses mostly Go AFAIK. Where I work we use Go in all
| our services. There's plenty of uses of Go. You just won't
| ever hear about them, because why would you? You see Java and
| Node because that's all you've ever worked with. I see
| Erlang, .NET and Go, because that's all I've ever worked
| with.
| RSHEPP wrote:
| Work at a large telecom co., who used to be Java only, I
| only write Go. Hn threads like this is when you realize
| it's core user base.
| gher-shyu3i wrote:
| It's only in hyped up circles where you hear that golang will
| displace Java. The latter is not going anywhere for the
| foreseeable future, and it keeps improving, whereas golang is
| stuck in the 70's.
| panzerboy wrote:
| Umm ... what exactly makes you say that?
| kaladin_1 wrote:
| Very soon whoishiring will start a thread for April. I bet
| you are going to see more Go opportunities than Java.
| kaba0 wrote:
| Just look at the recent Java 16 hn thread. Java is not going
| anywhere in the next 2 decades.
| preommr wrote:
| Go is not a simple language. Please learn from my mistakes, and
| ignore arbitrary metrics like how go has fewer keywords. The
| complexity doesn't go away, it's hidden away somewhere.
|
| If anybody wants to learn go, ignore everything about how easy it
| is to learn. Because it's extremely deceptive. Take time to
| actually read through a lot of the important underlying concepts
| like how slices work.
|
| Ignore comments about how go is simple to write. There's a fair
| amount of bad go code and people break rules all the time. From
| official sdks to standard libs. Go can be extremely difficult to
| both write and read. It's implicit interfaces and judicious abuse
| of interface{} can make tracing how a library is supposed to work
| a PITA. Writing go can be difficult because of a lack of some
| language constructs that leave you unsure how to proceed.
|
| If you can, use goland. I use vscode and it's... not pretty.
| Almost every single thread I've seen on reddit recommends goland.
| My experience with vscode has been very unpleasant, particularly
| with go plus.
|
| OTOH, things like criticisms about it's error handling are
| overblown. At best it's a mild nuisance, and more often than not,
| a good thing that makes error handling explicit and clear.
|
| There are many things about go that have made me appreciate it's
| existence. There are also many things that have left me
| absolutely baffled at how bad it is.
| kyrra wrote:
| VSCode still works fine with Go, but I do agree that Goland is
| better. Gopls[0] (the Go language server) has definitely been
| getting better, but it was not-so-great for a while (it locks
| up from time-to-time and you have to restart it, but that may
| be better now).
|
| [0] https://github.com/golang/tools/blob/master/gopls/README.md
| bogomipz wrote:
| I moved away from VSCode for Go simply because code
| completion was taking forever or sometimes failed to work at
| all. I believe that may hav e been related to gopls? Have
| others experienced this as well? Is that fixed now?
| RSHEPP wrote:
| Yeah I dealt with that for months, but it has greatly
| improved.
| kyrra wrote:
| In the command menu for VSCode (ctrl-shift-P on windows),
| there is an option called "Go: Restart Language Server",
| which tends to fix any problems with autocomplete or code
| navigation.
|
| I feel like I haven't had to use it as much recently.
| rufugee wrote:
| I tend to agree with you and had a similar experience. I found
| a lot to love about Go, but also found things which were just
| hard to fathom or reason about. For example, ask a Go
| programmer, given an interface, how you are supposed to find
| all implementations of that interface. As of a few months ago,
| there just wasn't a good answer for this, although supposedly
| you could get there with gopls if you knew how.
| blacktriangle wrote:
| Simple vs Easy rears its ugly head again.
| randomdata wrote:
| _> Ignore comments about how go is simple to write._
|
| Do people say that? I've never heard anyone claim that Go is
| simple to write.
|
| Pike, I believe (may have been someone else), claimed something
| to the effect that new grads with limited exposure to real-
| world codebases were able to understand existing projects
| written in Go more quickly than in other languages at Google. I
| have seen that message distilled down into "Go is simple to
| read."
|
| Go was built on the premise that people spend more time reading
| code than writing code and Go attempts to make tradeoffs
| towards reading optimization rather than writing optimization.
| Whether or not it is successful in that is another topic for
| another day.
| Thaxll wrote:
| Go is very simple to read and to write, I'm not sure how one
| can argue against that.
|
| Without prior knowledge you can jump into any code base and
| won't be suprised by something you never seen before or does
| not understand what it does. The language is simple to grasp
| because it has just a few concepts and keywords.
| derefr wrote:
| If by "read" here we mean "grok" -- i.e. to read and
| _understand_ well-enough to be able to modify without
| breaking the abstract guarantees the code makes, without
| documentation -- then I would say that the low level of Go
| 's concurrency primitives (relative to other languages
| modelling the same actor-based architecture, e.g. Erlang)
| means it takes more effort to "read" production-quality
| (concurrent, fault-tolerant, no resource-leaks, no data
| races) Go code relative to production-quality code written
| in other languages.
|
| Sure, when reading Go, you aren't really encountering new
| language features; but you're often being forced to
| _recognize_ things that _should_ be language features,
| which are instead implemented as design patterns. (And, at
| that, often with those patterns reified into code by new-
| ish programmers who don 't understand those design-patterns
| very well, rather than by language maintainers after much
| careful scrutiny.)
|
| It's like doing OOP in C, and having to mentally parse
| vtable structs into the object-model they represent -- with
| every project having done its own vtable implementation,
| all slightly different. Except that OOP is unusual in C,
| while concurrent infrastructure is near-universal in Go.
|
| When reading Go, I'm essentially mentally "decompiling" it
| as I go into a higher-level representation within my
| mental-model. "These 50 lines are a parallel map-reduce;
| these 200 lines are a read-through cache with per-key
| synchronization to avoid duplicate work; etc." I'd rather
| just read that higher-level representation directly!
| MisterTea wrote:
| As someone who cut their teeth on programming via C and c++
| Go did come surprisingly easy. My first interaction with it
| was a small change to a web thing and I had no trouble
| reading source code, understanding it, and making the
| necessary changes without ever learning to write a line of
| Go before. That alone is value.
|
| To me Go feels like a "modern" C language from 90's Bell
| Labs. Of course that is kind of true as Go is the spiritual
| successor to Alef and Limbo. Though it feels like it came
| out 10+ years too late.
| pjmlp wrote:
| Yes, Go is what Java 1.0 should have been, in 1996.
| MisterTea wrote:
| That was supposed to be Inferno/Limbo but sadly it didn't
| happen.
| pjmlp wrote:
| Yes, not only it did not happen, most people aren't even
| aware of it as they keep praising Plan 9 instead.
|
| In any case, Go is Limbo with a bit of Oberon-2 facelift,
| and as such a bit too late to the party.
|
| At least they might finally support some level of
| generics and catch up with CLU.
| MisterTea wrote:
| Because plan 9 was developed naturally in the Lab as an
| evolution of Unix research.
|
| Inferno on the other hand was a blunt force attempt by
| Lucent to leapfrog Sun by halting Plan 9 development for
| a whole year forcing the team to instead work on Inferno.
| It was a commercial project to produce a product which
| was in stark contrast to the more academic/research
| oriented development of Plan 9.
|
| Unfortunately, this hamfisted attempt by Lucent left
| Inferno in a state of Limbo, pun intended. The target was
| more along the lines of embedded systems like set top
| boxes and early PDA's. The Dis VM also suffers from hard
| coded 32bit pointer magic which means it only builds on
| 32bit plan 9 or in a 32bit chroot under a unix-like for
| hosted mode. And finally, the Charon web browser has a
| bug that crashes the Dis VM. I have yet to see it boot on
| bare metal hardware in its entirety. These reasons are
| why Plan 9 gets all the love, it works out of the box on
| 386/amd64 and arm32/arm64 (Rpi, Zynq, etc)
|
| Though not all is lost. Someone is working on getting it
| to build on 64bit 9front and OpenBSD, though the code is
| very much a WIP (if interested, hop into #cat-v on
| freenode and ask about the Inferno 64 bit port). It's not
| completely dead. Patches welcome :-)
| pjmlp wrote:
| Interesting background history, do you have some pointers
| to read more about such stuff regarding Inferno?
| MisterTea wrote:
| I believe that info came from a plan 9 user who interned
| at Bell Labs in the 00's. Though honestly you can get
| much better answers from the source by posting to the
| 9fans mailing list. Charles of Vita Nova, current owner
| of the Inferno code is a regular on that list as are many
| of the original Bell Labs folks.
| pjmlp wrote:
| Thanks
| pxue wrote:
| it's simple to write ONCE you understand and learn the
| idiomatic code.
|
| some people call not having native string/int/whatever
| sorting methods is "hard to write".
|
| some people think the verbose `if err != nil` every other
| line is also "hard to write"
|
| again, there is an upstart cost, which is to integrate
| yourself into the language community.
| makapuf wrote:
| Golang does have a few simple types sorting functions
| such as string and int
| https://golang.org/pkg/sort/#Strings. Now that generics
| will be out, could we even have generic sort functions ?
| egeozcan wrote:
| you cannot write a generic function that returns a modified
| slice without losing types. that, in my book, means hard to
| write.
|
| ...which makes it also very easy to read.
| unchar1 wrote:
| I think the word you're looking for is "tedious". Go is
| both simple and tedious to write. I'd actually argue it's
| tedious _because_ of its simplicity.
| nicoburns wrote:
| But all that boilerplate also makes it hard to read. You
| have to pick out the meaning amongst a bunch of noise.
| marcus_holmes wrote:
| Not once you're used to it. Humans are good at spotting
| patterns, and once you're used to the patterns of the
| boilerplate it becomes easy to read and you only notice
| the anomalies.
|
| The famous "if err != nil {" boilerplate becomes expected
| after each call and you only notice if it changes.
| hnlmorg wrote:
| I don't see the point of cherry picking highly specific
| examples because for every argument there will be just as
| many counterarguments from other domains.
|
| To be more specific: the point isn't whether Go is
| "always" simpler to write but whether it is _generally_
| simpler to write. I think the latter is true for all the
| domains I 've written code in Go and I've solved some
| pretty hard problems in Go (check out my Github
| repositories if you don't believe me).
|
| The awesome thing about programming languages is that
| you're free to pick another language if that is a better
| fit for any specific domain or even personal preference.
| Hence why I've worked in more than a dozen different
| programming languages over the years. So rather than
| moaning that Go doesn't fit a particular pattern where
| you need to rely on generics, perhaps use a language that
| has generics to solve that problem and save Go for the
| occasions you don't need generics (which, if we're all
| honest, isn't something we need to rely on half as much
| as people claim when moaning about the lack of features
| in Go).
|
| As a veteran developer, what really annoys me the most is
| people who pick a language that isn't well suited for
| solving the problem at hand and then moan that language
| needs to change, rather than developers picking the right
| tools for the job. I'd rather see a language lack
| features but focuses to serves its core demographic well
| than see everything and the kitchen sink is thrown at it
| and everyone using it even when they know they shouldn't
| simply because they're too afraid to learn anything new.
| What we need is more appreciation that "general purpose
| languages" doesn't mean "should be used to do practically
| anything in". Then I'd think we'd all get along better.
| egeozcan wrote:
| I meant it as a random example. I do not dislike go. As
| I've stated below, I actually am learning it (more like,
| the conventions around it), just for fun.
|
| I find it especially powerful for writing tools.
|
| That doesn't remove my rights to nitpick its shortcomings
| though.
| q3k wrote:
| I've been writing Go full-time, professionally for around
| 4 years now. Backend software, mostly distributed stuff,
| tools and services - the bread and butter of what Go's
| designed to be good at. On the side, I occasionally write
| some Rust, Haskell, and other 'good' languages.
|
| I have kept a counter of many times I've told myself,
| over the past years, 'I wish Go had generics, this would
| really make my life easier right now'. It's currently at
| 5.
|
| In my experience, the supposed issue of a lack of
| generics is _extremely_ overblown with regards to real
| world use. Sure, it would be nice to have them. I
| would've really liked them to exist a month ago when I
| was writing a generic container. But they're not going to
| make the language that much better for me, and there's
| always going to be more things PL people lust after
| (usually the next candidate would be GADTs, "Go does not
| have algebraic data types!" coming to HN comments very
| soon).
| morelisp wrote:
| As a counterpoint: I also write Go in this same space. I
| _like_ Go - I find most of its design goals align closely
| with my personal preferences (avoidance of syntactic
| noise, fast compile times, right-sized standard library,
| sufficient control over memory without having to worry
| about memory safety).
|
| If I kept a similar counter for the past 3 years, it
| would be at least _five per day_.
|
| Every time I `return x, err` and it's not a true tuple -
| and it almost never is - I wish I was returning an
| `Either<X, error>`. That's constant.
|
| Every time I use atomic.Value (often) or sync.Pool (less
| often) or sync.Map (almost never because I end up rolling
| my own stupid map+mutex).
|
| 90% of the time I want to say a pointer can't be null.
| 100% of the time I want to handle optional JSON or SQL
| fields.
|
| Fairly often, like > 30% of the time, when wrapping
| serdes or DTO conversions around data streams.
|
| I don't believe the level of generics required to support
| these use cases requires compromising the other goals of
| Go. The deficiency should have been obvious as soon as
| they introduced `sync.Map`.
| rob74 wrote:
| > _there 's always going to be more things PL people lust
| after_
|
| How about non-nullable types?
| q3k wrote:
| Sure, put that on the pile labeled "things that sometimes
| bother me, but I forget they're even an issue when I talk
| about Go with others", next to generics.
| Thaxll wrote:
| Then you write 2 functions, what you're talking about is
| a different question.
| adkadskhj wrote:
| Maybe. If you have to remember two functions to
| _understand_ the code, is reading really easier? I
| imagine reading implies understanding, and while i
| definitely think Go is easier to read without
| understanding, i don't think that's the real implication.
| egeozcan wrote:
| if having to write a separate function for each type of
| container is easy for you, then I can only respectfully
| disagree :)
|
| I'm saying this as someone who is learning go for fun.
| throwaway894345 wrote:
| I would argue that it only makes it hard to write type
| safe generic functions that return modified slices. If
| you're writing generic code for the sake of writing
| generic code, Go is probably going to give you a bad
| time, but if you're trying to solve real problems, you
| can get a _very_ long way with slices, maps, and
| interfaces /functions.
| erik_seaberg wrote:
| filter/map/reduce are more productive than anything I
| could write without them.
| fwip wrote:
| Then you can go ahead and use one of the many code
| generation libraries out there to handle it for you in a
| type-safe way.
|
| Here are three options that were on the first page of
| google:
|
| * https://github.com/kulshekhar/fungen
|
| * https://github.com/awalterschulze/goderive
|
| * https://github.com/cheekybits/genny
| throwaway894345 wrote:
| I'm very skeptical. This kind of argument only makes
| sense if your programming is bottlenecked by your typing
| speed. It's trivial to write these functions as for
| loops, the only difference being the number of key
| presses.
| erik_seaberg wrote:
| filter is obvious at a glance, where all loops look
| similar. Generating a wall of boilerplate is easy, the
| problem is that we can't just ignore it and read a
| summary. Essentially I'd like to decompile Go to what
| could have been written in a powerful language.
| throwaway894345 wrote:
| Wall? var out []X for _, x :=
| range elts { if condition(x) {
| out = append(out, x) } }
|
| That's so easy I typed it from my iPhone and anyone
| looking at it can infer at a glance that it's filtering a
| list. If you are deeply worried about it, throw a comment
| at the top of the block.
|
| I too like terse code, but it's because it makes me feel
| smart, not because it's easier to read or more
| maintainable. I'm having a blast writing Rust for my
| hobby project, making everything super DRY and free from
| boilerplate, but I don't pretend that I'm saving myself
| time or making things more readable or maintainable
| should someone else come across it.
| eweise wrote:
| elts.filter(condition(x)) way more readable.
| theshrike79 wrote:
| Only if you know what a filter is and how the condition
| is parsed.
|
| In more cases than one the condition is a lambda-
| monstrosity shoved in the filter function, which makes it
| even harder to parse.
| marcus_holmes wrote:
| Not if you're not used to it. Literally had this over the
| past few months working with a junior programmer who had
| a really hard time understanding stacked map()s and
| filter()s but understood them easily when I unrolled them
| into nested for loops.
| eweise wrote:
| The junior programmer would have been much better off
| learning how a filter function works so they could be
| productive in almost every other language besides Go.
| marcus_holmes wrote:
| This was Javascript. And yes, I was teaching him how
| filter functions worked. But the point remains that if
| you're not used to them, map() and filter(), especially
| when stacked, are not that readable.
| adkadskhj wrote:
| > I have seen that message distilled down into "Go is simple
| to read."
|
| I think the two are related, directly. However in my
| experience i don't even agree with Pike. Go is not easy to
| read. Yes, a single small function in Go is much easier to
| read (perhaps) than X lang. However Go requires a huge
| (brain)memory table to remember everything, because it
| spreads logic out. So you have to remember X function, scroll
| up, look at Y function remembering how it interacts with X,
| etcetc.
|
| > Whether or not it is successful in that is another topic
| for another day.
|
| I guess i bikeshedded, sorry :s
| rob74 wrote:
| > _Pike, I believe [...], claimed something to the effect
| that new grads with limited exposure to real-world codebases
| were able to understand existing projects written in Go more
| quickly than in other languages at Google. I have seen that
| message distilled down into "Go is simple to read."_
|
| Yeah, it was Pike, and I have also seen it distilled (in bad
| faith) into "Go is a primitive language for inexperienced
| programmers, so it's beneath me to touch it". And yes, it
| _is_ easier to write and read compared to other languages
| (old and new), but it does have some concepts that you should
| follow to write "idiomatic" Go code, e.g. don't throw panics
| as liberally as you would throw exceptions in other
| languages, use composition and interfaces where you would use
| inheritance in other languages etc. But I'm afraid people who
| have been indoctrinated with disregarding Go as "simple", but
| want to try it nevertheless (or are forced to use it), won't
| take the time to get into these details, and will see their
| preconceived opinions confirmed...
| dvfjsdhgfv wrote:
| > Do people say that? I've never heard anyone claim that Go
| is simple to write.
|
| The article we are discussing now has a big subtitle "A
| simple language."
| tene wrote:
| This really matches my experience, in that learning the Go
| language is very simple, but learning to correctly use the Go
| language to reliably build correct programs is much more
| difficult. The Go compiler (and other tooling like go vet and
| the race detector) gives me very little assistance or
| confidence in my work. The Go standard library is similarly
| very weak, leaving me to repeatedly re-implement things that
| are taken for granted in other languages, like common
| collection operations.
|
| One big example is Go slices, which are "easy to use" and "just
| do the right thing" up until they don't. If you append to a
| slice, it might or might not allocate a new backing array
| depending on the slice capacity, so whether your function is
| mutating an original or not can suddenly change based on
| changes in other parts of the code, and it's a huge pain to
| track down bugs like that.
|
| Go's channels are "Easy to get started with", but very
| difficult to correctly compose, or do anything nontrivial with.
| Reading from a closed channel will "successfully" generate zero
| values instead of failing to read a value. You have to replace
| your variables with a nil channel instead.
|
| When writing Go, I feel like programming by coincidence. With a
| lot of careful thought and work and testing, I can arrange for
| something that works, but it's fragile under refactoring and
| maintenance due to spooky action at a distance.
|
| None of the stdlib collections are threadsafe, but if you
| mistakenly share one between threads, it works fine up until
| you hit sufficient concurrency to have multiple concurrent
| mutations.
|
| Go is "easy" due to garbage collection, but that only handles
| memory, and offers you zero assistance in handling any other
| resources. There's no destructors, and no RAII, so you still
| have to carefully manually manage resource cleanup for files,
| database connections, locks, mutexes.
|
| Go's type system is too weak to express a mutex owning its
| guarded value, so it's left up to careful code review to ensure
| that the guarded value is only accessed while the mutex is
| locked.
|
| I feel like "the language" is simple, sure, but to successfully
| use it, you have to also learn many little constructs you have
| to repeatedly type out, and techniques to protect yourself from
| all the sharp edges.
|
| For me, the Go Language was faster to learn than the Rust
| Language, but learning to reliably build correct programs with
| Rust was _way_ easier than learning to reliably build correct
| programs with Go.
|
| I like Rust because I am a mediocre programmer with poor
| working memory. Rust lets me build abstractions I can rely on,
| and reason locally in small parts while working on a program
| larger than I can easily fit into my head.
|
| Go makes some operations "easy", but unfortunately also makes
| shooting myself in the foot much easier than doing something
| safe and correct.
|
| The Go language itself is very simple because it abdicates all
| responsibility for correctness, leaving it entirely up to the
| programmer. You still need to handle all of the same
| responsibilities regarding ownership, resource lifetimes,
| locking, thread-safety, error-checking, exhaustiveness-
| checking, etc. but Go leaves all of that up to individuals to
| learn for themselves through trial-and-error, and ignores all
| advances in PL theory on how languages can assist with these
| problems.
|
| I could understand some of the appeal of Go if it was people
| saying they like to use it for half-assed one-off scripts that
| don't grow to large sizes and don't have any long-term
| maintenance, but instead I keep seeing people build large
| production systems with it.
| coryrc wrote:
| > but learning to correctly use the Go language to reliably
| build correct programs is much more difficult
|
| I feel this strongly as someone who prefers to write code
| which always works versus the "works except on edge cases"
| approach of most Go code. It's a step up from bash though.
| adkadskhj wrote:
| > OTOH, things like criticisms about it's error handling are
| overblown. At best it's a mild nuisance, and more often than
| not, a good thing that makes error handling explicit and clear.
|
| Yea, i'm a bit critic of Go (used it professionally for ~5
| years, but no longer), but it's error handling is fine. Would i
| like Rust's `?` error handling syntax? Yes. Would i prefer
| better language tools for error handling (like enums/etc)
| rather than usually just wrapping strings? Absolutely.
|
| But the actual _need to error check_ itself is fine. I think
| it's funny, because to me the Go audience is one similar to
| NodeJS/JavaScript, aka one that favors features to improve
| prototyping. And while much of Go feels (at first glance) to
| promote this, the error handling does not.
|
| I prefer Go error handling. But i wonder if Try/Catch would
| have been more inline with much of Go's audience.
| david-cako wrote:
| The complexity is about the bare minimum to express concepts
| like concurrency, pointers, and interfaces, in my opinion. The
| ways Go seems complex are because it doesn't try to hide how
| memory works as much as other memory-managed languages, and in
| turn, as an engineer, you can write application and web-level
| code that performs almost as well as C and gets you thinking
| about things like a C programmer. I think Go just seems
| familiar to people that come from a variety of languages.
|
| For me, the simplicity, batteries-included, and minimal
| primitives are a breath of fresh air, whereas in many languages
| I've felt like I have to learn "a whole new thing" each time I
| plug in a new library or try a new framework. Go has a web
| server, JSON, SQL, crypto, compression, and more built in, and
| it's all stuff you'd want to use directly in production. In Go,
| code and docs are just easier to write and navigate too.
| Compare, for instance, the prevalence of Reader/Writer types to
| how all-over-the-place implementations of buffers and
| asynchronous code are in other languages and ecosystems, or how
| many different build systems, dialects, and frameworks most
| languages have. The locality of most Go packages means you'll
| find better docs and help, and more canonical examples of how
| to do something.
|
| Swift is another "deceptively simple" language to me. Swift has
| quite a few features, which means more prerequisite knowledge
| to read code "in the field". You're less likely to understand
| code by looking at it because there's more ways it can pan out
| while the developer is thinking about how to write it. I found
| that to be an especially big problem with JavaScript; I
| generally tell people to start writing JavaScript with a
| particular toolchain like React/TypeScript so they can set up a
| project and get on the right track fast. Go's ecosystem is
| opinionated but still just flexible enough, as I would say most
| of the features are.
| strken wrote:
| When people say Go is a simple language, they mean that Go, the
| literal language, is simple. Some people are also claiming that
| the programs written in Go are simple, that the ecosystem is
| simple, or that using Go is easy, and those people are probably
| wrong. However, Go the language _is_ actually simple.
|
| Here is the Go spec: https://golang.org/ref/spec. Firefox's
| print dialogue tells me it's 105 pages long. You can read the
| spec in an afternoon and digest most of it.
|
| Here is the ECMAScript 11.0 spec (known as JavaScript to its
| friends): https://262.ecma-international.org/11.0/. Firefox's
| print dialogue tells me it's 1181 pages long.
|
| Here's the Java SE 16 spec:
| https://docs.oracle.com/javase/specs/jls/se16/jls16.pdf. It's
| 844 pages long.
|
| I can't post the C++20 spec because it's an ISO standard and it
| costs $399AUD for the privilege of reading it, but it's 1853
| pages long in PDF form:
| https://www.iso.org/standard/79358.html.
|
| On a factual level, Go is a simple language, but so is the
| language Brainfuck, which has a sort-of-spec that's 9 pages
| long: https://github.com/brain-
| lang/brainfuck/blob/master/brainfuc.... Simplicity is not ease
| of use.
| pjmlp wrote:
| The C++ standard includes the standard library.
|
| If you want a fair comparisasion, include the standard
| library for the other languages.
| derefr wrote:
| Eh, that's a bit problematic -- there's no standardization
| in what's _in_ a standard library.
|
| Some languages have stdlibs that just contain "stuff
| everybody needs" -- stuff every app or library written in
| the language will use (common data structures, concurrency
| primitives, etc.), such that anyone who "knows the
| language" would also be expected/required to know (or at
| least know _of_ ) those components, if they have any hope
| of being productive in the language.
|
| But other languages have huge stdlibs, that include a bunch
| of stuff that almost nobody is even aware of, such that
| most developers won't actually need to know about it in
| order to effectively maintain other people's code in the
| language. These are essentially just weird niche libraries
| that happen to ship with the runtime for some reason.
|
| Examples of weird niche libraries that are technically
| "stdlib":
|
| * PHP has an Ingres driver built in. That's Ingres, the
| predecessor to Postgres.
|
| * Ruby ships with a CJK character-normalization CLI
| utility.
|
| * Erlang/OTP has "Megaco"
| (http://erlang.org/doc/apps/megaco/megaco_intro.html) -- an
| H.248 media gateway daemon library.
|
| Admittedly, languages do tend to _gradually_ factor these
| weird niche bits out into separate packages. (Ruby just
| moved almost all of its stdlib into ecosystem packages in
| 3.0. Some ecosystem packages are just now install-by-
| default -- but maybe won 't be in the future.)
|
| Also, the behavior of these weird niche bits is _not_
| usually specified as part of the language 's spec... but
| that doesn't mean much, as often, these languages don't
| even _have_ specs. In those cases, the reference
| implementation _is_ the spec -- and so, if the reference
| impl includes these libs, "the language" includes these
| libs.
| LukeShu wrote:
| Working from a freely available draft of the C++ 2017 spec:
| http://www.open-
| std.org/jtc1/sc22/wg21/docs/papers/2017/n465...
|
| In total, it's 1622 pages. Without the cross-references and
| the index it's only 1486 pages. Also excluding the standard
| library, it's 520 pages.
|
| There, the fair comparison is: Go: 105
| pages C++17: 520 pages
| pjmlp wrote:
| Sure, thanks for putting in the effort.
|
| By the way, Java, Python and .NET ones top the C++ one.
| nicoburns wrote:
| > When people say Go is a simple language, they mean that Go,
| the literal language, is simple.
|
| Perhaps. But what use is a language that is simple if it
| doesn't make it simpler to use or easier to learn? I think
| most people who claim that Go is simple are claiming the
| latter, because the former is mostly uninteresting. It's good
| for IDE support I guess.
| eikenberry wrote:
| Pencil is a simpler medium than oil paints, but that
| doesn't make it any easier to do a good portrait with it.
| Saying its a simple language is expressing a trait of the
| language that some people may like or find they have an
| affinity for. People seem to get stuck with the idea that
| programming languages can only be compared via objective
| criteria where as we seem to use these sorts of signals to
| help each other find mediums we like.
| strken wrote:
| It's a tradeoff. You get a simple language without a lot of
| surprising features, but sometimes code is very verbose;
| sometimes problems that would be trivial in other languages
| require unfortunate solutions like cgo, reflection, strange
| hacks[0], or code generation; and sometimes the "sensible"
| opinionated ecosystem doesn't fit how you want to work.
|
| [0] https://golang.org/pkg/sort/#example_
| simiones wrote:
| Well, to be fair, the Go spec is missing several parts of the
| language, such as finalization, thread safety (the memory
| model, sync points or other happens-before relationships),
| goroutine memory/stack usage, anything to do with go modules.
|
| Still, even if they added these, it would likely stay
| significantly shorter than even Java.
| remus wrote:
| > finalization, thread safety (the memory model, sync
| points or other happens-before relationships), goroutine
| memory/stack usage, anything to do with go modules
|
| I dont think it affects your point but those are
| implementation details rather than features of the language
| itself. Obviously it's still important to understand the
| language implementation so you can make reasonable guesses
| about performance etc. when you're programming.
| simiones wrote:
| With the exception of goroutine memory/stack usage
| perhaps, these are not implementation details - they are
| core parts of the semantics of the language (especially
| since asynchronicity is a fundamental aspect of the
| language through goroutines).
|
| For example, is this piece of code correct?
| x := 7 go func() { if x == 7 {
| fmt.Println("x = 7") } else {
| fmt.Println("x != 7") } }() x = 8
|
| What are its possible valid outputs? (for the record, as
| far as I know this is incorrect code in Go, as atomic
| access is not guaranteed for any variable, so not only
| could this print any of the two outputs, it could also
| observe invalid values for x)
|
| What about this code: x := 7 c :=
| make(chan struct{}, 0) go func() { if x ==
| 7 { fmt.Println("x = 7") } else {
| fmt.Println("x != 7") } c<-struct{}{}
| }() <-c x = 8
|
| Can you tell from the language spec whether this code is
| safe, and what it's output will be? (~~it's not safe, as
| far as I know~~ reading the memory model[0], I believe it
| is safe).
|
| [0] https://golang.org/ref/mem
| erik_seaberg wrote:
| To be fair, Java's memory model was also pretty broken
| for several years.
| kibwen wrote:
| The point is that other language specifications do
| include these things, which makes comparing their length
| to the Go specification inaccurate.
| hnlmorg wrote:
| > _Ignore comments about how go is simple to write. There 's a
| fair amount of bad go code and people break rules all the
| time._
|
| This is one of the most famous straw man arguments made in
| software development and I've seen it used against a plethora
| of different programming languages -- each time completely
| missing the point that you can get bad developers writing bad
| code in any language. The fact it happens in Go isn't a
| testament not to how difficult it is but rather how good of a
| job the language has done attracting newer developers.
|
| > _Go is not a simple language. Please learn from my mistakes,
| and ignore arbitrary metrics like how go has fewer keywords.
| The complexity doesn 't go away, it's hidden away somewhere._
|
| I completely disagree. Having fewer keywords does make Go
| simpler to learn and simpler to read other peoples code. The
| opinionated nature of Go also makes it simpler to collaborate.
|
| Writing software isn't simple but that complexity of turning
| ideas into code doesn't change significantly from one language
| to another (generally speaking). You still have to solve a
| problem using logic and functions. I find the harder problems
| with software development is collaboration (eg ensuring
| everyone is following the same coding styles) and reading back
| old code. Go makes those things easier than some -- not all but
| definitely some -- languages.
|
| I say this based on 30 years of experience writing software in
| more than a dozen different programming languages.
| onislandtime wrote:
| To me, compared to other languages, I find Go easier for
| expressing my ideas in code. People seem to argue as if there
| was an objective truth. Different people may have different
| learning styles and working requirements. I'm not programming
| full-time so I prefer a simpler language so I don't forget. A
| full-time programmer may want to invest in a more "complex"
| language. See, you are all right.
| doublerabbit wrote:
| > Having fewer keywords does make Go simpler to learn and
| simpler to read other peoples code
|
| I partly disagree. It might be easier for you with 30 years
| of experience. Sysadmin with 8yrs of experience and having to
| manage operations utilizing Go is not easy.
|
| The code looks neat on the page; under the hood is really un-
| understandable at times unlike Perl, Ruby, TCL where the code
| is staring you in the face. The importation of modules off
| github is fundamentally wrong too.
| hnlmorg wrote:
| > _The code looks neat on the page under the hood is really
| non-understandable at times. Unlike Perl or TCL where the
| code is staring you in the face._
|
| Are you able to elaborate on this a little more? I love
| Perl and in fact that was my favourite language for a long
| time (despite all of its warts). But languages like Go are
| a lot more explicit that Perl so I'm not really sure what
| you mean by "under the hood" and "code is staring you in
| the face.
|
| > _On vent: I also really loathe importing modules off
| github._
|
| I must admit that really annoyed me too but in fairness
| it's a pretty common pattern (eg brew, npm, etc). In a way
| Perl (CPAN) is an edge case rather than the norm. The
| difference is other systems add a shim around the code
| source even if they do still pull directly from (or from a
| cache populated directly from) Github et al
| doublerabbit wrote:
| Sure.
|
| We use Prometheus exporters, most of the exporters are
| written in Go. And this is a snip from the vmware-
| exporter for our VMware estate.
| metrics.go
|
| The first throw was this: import (
| "context"
| "github.com/prometheus/client_golang/prometheus" log
| "github.com/sirupsen/logrus"
| "github.com/vmware/govmomi/find"
| "github.com/vmware/govmomi/view"
| "github.com/vmware/govmomi/vim25/mo"
| "github.com/vmware/govmomi/vim25/types"
|
| So as it currently stands I have no idea what those
| modules are and what I am loading. Browsing each of those
| repos sure will tell me, but that's not my role. My role
| is to make X operational.
|
| And if that repo doesn't exist anymore and you go to
| compile, it fails. More overhead if I need to make
| changes to any of those modules. I would need to git
| clone it somewhere, make the change and then either
| recommit it to git, or do something to make it locally
| available. At least with NPM, CPAN they are local to the
| file system.
|
| So lets start: var (
| prometheusHostPowerState =
| prometheus.NewGaugeVec(prometheus.GaugeOpts{
| Namespace: namespace, Subsystem: "host",
| Name: "power_state", Help: "poweredOn 1,
| poweredOff 2, standBy 3, other 0", },
| []string{"host_name"})
|
| I understand all of that. Power_state, display the help,
| power status description etc, however
| prometheus.NewGaugeVec -- Sounds great. What is it? Where
| do I find this? What module is this related too?
|
| That's where it falls down for me. I now have to duck in
| to the rabbit hole of github to find out where that
| function is phrased and in this sense "under-the-hood"
| could also count for library .pm files in perl, but now
| having to navigate GitHub really messes with my workflow.
| BarkMore wrote:
| You do not need to go down the Github rabbit hole. The
| symbol prometheus is from the package
| github.com/prometheus/client_golang/prometheus. Use _go
| doc github.com /prometheus/client_golang/prometheus_ to
| read the documentation from your local copy of the
| package. Use _go list -f {{.Dir}} github.com
| /prometheus/client_golang/prometheus_ to find out where
| your local copy is located. If there is only one
| prometheus.NewGaugeVec in your workspace, then the
| command _go doc prometheus.NewGaugeVec_ shows the
| documentation for function and reports the package where
| it 's defined.
| doublerabbit wrote:
| Yes, it states the obvious, but I'm trying to point out
| what I mean. It's not always so golden as such.
| q3k wrote:
| > So as it currently stands I have no idea what those
| modules are and what am I loading? vim25? Is that the
| text editor vim?
|
| Take any of these imports, append it to
| https://godoc.org/, and see.
|
| For example, github.com/vmware/govmomi/ becomes
| http://godoc.org/github.com/vmware/govmomi/ , which tells
| you: govmovi: A Go library for
| interacting with VMware vSphere APIs (ESXi and/or
| vCenter).
|
| Everything underneath govmovi is subpackages of it, so
| `find`, `view`, `vim25/mo`, and `vim25/types` are all
| govmovi packages. You can also visit them on godoc to
| read documentation, if the code authors followed
| documentation best practices.
|
| These are imports like in any other language. They are,
| however, nearly always based on a global URL, and thus
| have a godoc page that you can visit and read the docs
| for immediately. They are also always qualified, so if
| you wanna find all all uses of govmovi/vim25/mo, just C-f
| for "mo." in your codebase. No `from foo import *`
| equivalent exists in Go, which is one of my favourite
| features of this language.
| doublerabbit wrote:
| Sure. Fair to say that godocs is to cpan of perl.
|
| But Go doesn't present you the code on disk. I have to
| hunt somewhere else with a reference. With a library
| file, I know that prometheus::exporter::blah is related
| to the perl module prometherus, exporter subroutine blah
|
| I need the code in front of me to understand how it's
| interacting; the whole github ruins that for me.
| hnlmorg wrote:
| > _But Go doesn 't present you the code on disk._
|
| Yes it does. You couldn't compile the modules if they
| weren't on disk :)
| doublerabbit wrote:
| But only at compile time.
| q3k wrote:
| `go mod download`, if you're using go modules, will fetch
| you the deps.
|
| This is no different, to me, than downloading a tarball
| of Python software with requirements.txt and not running
| setup.py or pip install. I don't understand the problem.
| doublerabbit wrote:
| Right, then it could be I wasn't aware there is a "go mod
| download". If it actually gives me a file I can modify
| without having to create any repo, special things to
| apply the changes then that will assist me in the future.
|
| Go isn't my thing and the less time I play with it, the
| happier I am. This is only my experience of it, and my
| experience is it acts friendly, but is a faff.
| hnlmorg wrote:
| > _the less time I play with it, the happier I am._
|
| There lies the problem. If you don't want to invest the
| time to learn the tools then you can't really complain
| that your screwdriver is rubbish at hammering in nails.
| And it doesn't matter how easy or hard any programming
| language is, all languages will have a learning curve
| that people need to be prepared to undertake.
| doublerabbit wrote:
| It's not that I don't want to, it's more I don't have the
| time to invest upon. I'd read all the national library
| books if I could, but I just don't have the time.
|
| End of shift, I walk away from my screen and try to do
| something other than. I'm burnt out enough by the tech
| field as it is.
| q3k wrote:
| It seems to me that the problem here is your job, not Go.
| You could substitute Go here for any other language or
| technology that you don't know well and for which you're
| not given adequate time to learn the basics of, and you'd
| get the exact same result.
| doublerabbit wrote:
| My job is solid. I have time to do such. I would rather
| just use my time available on have more pressing issues
| then a language I don't really want to use.
|
| Sure knowledge is boss, but my job is fine. It's not the
| job at fault.
| q3k wrote:
| So it seems clear to me? You don't want to use the
| language, you don't want to learn the language, no-one is
| forcing you to use the language, then don't use the
| language.
|
| What are your expectations? Is it that every language
| should be readable to people who know Perl? Is it that
| you shouldn't be reading or modifying the source code of
| open source projects? How could this work better in an
| ideal world? I am puzzled.
| doublerabbit wrote:
| Why are you turning this in to such a pedantic thing? I
| am not a programmer. I am a systems administrator who
| administrates systems. Is that not easy to grasp?
|
| When my job is 98.9% something else than programming, I'd
| rather be learning AI, Robotics, History, Psychics,
| Gardening, Glass Blowing than a language I'll never use.
|
| I've explained it a case of "Can you get this to work"
| Yes/No. If no, I move on to something else. That's my
| line of work.
|
| If you want me to monitor,configure,administrate
| something, then it should be simple. Presented to me in
| one folder with all packages not downloaded from some
| corporate hell-hole of a website because it's the norm
| for younger developers. Am I not allowed to have that
| opinion?
|
| I will research on how to operate but that's it. Life's
| busy enough that I don't have time to further research on
| how to setup individual environments. I've just wasted 10
| minutes typing this message to reply rather then
| configuring an openldap server for user authentication,
| Luckily I'm on lunch.
| q3k wrote:
| I'm not trying to be pedantic. Please do not assume bad
| faith.
|
| I'm just trying to understand that worldview, which just
| seems drastically different from mine, even though we
| both seem to be generalists. If there is something that
| Go, or any other product, could do better to be better
| suited to your workflow, I would like to know what it is.
|
| I don't write Perl, but if I had to qualify some piece of
| software that used it at work, I would make time then to
| learn as much of the basics of it that is needed to more
| easily get by. Even if it meant a day of reading
| Perl/CPAN docs to do 15 minutes of actual 'work',
| especially if the alternative is one or two days of
| blindly stumbling around to then not even be exactly sure
| if my 'yes/no' answer was correct. I don't even see much
| of a difference between learning something and just
| working with it - I can't imagine not having a browser
| window open with the docs/source code/whatever of what
| I'm currently working with.
|
| In that way I've learned a fair bit of technologies I
| would have never touched otherwise, but now their
| knowledge, even at a surface level, is worth more than
| the sum of the products.
| doublerabbit wrote:
| I mean no offense and sorry for my angst if it came that
| way. It's frustrating when I can't paint my view and then
| get battled to death because of it.
|
| TCL.
|
| TCL is the only language workflow that has worked for
| without any stress. proc SomeProcedure
| {variable} { Code it to do something for
| yourself }
|
| save, run and it works. No need to include modules, no
| need to download anything. I use my own TK/Gui interface
| which does stuff for me to make my life easier. And if I
| handed it to you, it would be in one folder with all
| files present no dependencies required. However I
| understand life is not like that unfortunately.
|
| > I can't imagine not having a browser window open with
| the docs/source code/whatever of what I'm currently
| working with.
|
| I don't. If at any point I need source code, I'll
| download it locally and compile/run it first. Then edit
| it learn the logic and flow of the program. I'm in
| terminal 99% of the time, orchestrating systems ranging
| from FreeBSD to Linux and AIX, if a browser is open it's
| for Slack, emails.
|
| I am someone who wants to type "man something" and get a
| man page of it. vim Library/file.pm and be able to view
| the code under the hood for that specific project. That's
| simplicity and that's how it should be -- The over-hassle
| of downloading from git, forking it, apply push,pull
| changes just isn't my street specially assuming my box
| I'm working with has internet.
| hnlmorg wrote:
| The issue is you presented opinion as fact.
|
| Opinion: I don't enjoy Go as much as Perl. [PASS]
|
| Opinion: I'm more comfortable with Perl because I've
| spent more time in it. [PASS]
|
| Both are perfectly acceptable.
|
| However you made comments about objective truths that
| were incorrect:
|
| Truth: Go doesn't download modules to disk. [FAIL]
|
| For what it's worth, I really like Perl too. Us two are a
| dying breed in that regard. I was in two minds whether to
| reply because of that respect I have for fellow Perl
| hackers. But you kept repeating the same falsehoods as
| fact :(
|
| Take your latest comment for example, you can bring up
| the Go docs for packages in the terminal as well:
| go doc $PACKAGE
|
| So even there your Perl point is still equivalent to Go
| on an objective level. But I don't blame you for not
| liking/enjoying a language on a personal level.
| mixedCase wrote:
| Okay so you don't want to spend time learning new stuff
| but at the same time you don't want to be left behind.
|
| You want a stagnant field. Sorry if I come across as too
| blunt, but you chose the wrong line of work if you don't
| like change. You'll still be able to work with the same
| old, boring but proven tech for the rest of your life,
| but face the fact that you'll be more inconvenienced by
| the reality you live in as time passes.
| doublerabbit wrote:
| What? I want change, I like change. I understand change
| and I will learn change.
|
| However when I have more pressing matters and when I am
| not requiring to use Go for my day to day life I have no
| purpose to put further education in to it other then
| enough to get by with.
| hnlmorg wrote:
| You can import them at any time. Most people import early
| so that IDE's can inspect the packages (eg for completion
| tools etc).
|
| Again, just like with Perl.
| q3k wrote:
| If you want to read the code, each godoc name can be
| clicked to directly redirect you to the source code of
| what you're looking for, eg. to a github page code
| viewer.
|
| Depending on whether you use gomodules, GOPATH, or any
| other build system you also can find the files locally to
| grep through them or use your text editor to read them
| locally. You can also override import resolution to point
| to a fork (eg. of any module if using gomodules), if you
| want to test drive some local patches.
|
| I do a _ton_ of code reading in my work, and I find using
| Godoc for that probably the best experience of any
| language (second only to maybe Haskell/Hoogle, but there
| you get much more difficult-to-grok-at-a-glance code).
| doublerabbit wrote:
| > You can also override import resolution to point to a
| fork (eg. of any module if using gomodules), if you want
| to test drive some local patches.
|
| So much overhead where time is limited. I shouldn't need
| to fork packages, I don't want to fork.
| q3k wrote:
| It's one `cp -r` and a 1 line change in go.mod [1]. You
| can also just `go mod vendor` to have all modules land in
| a `vendor/` directory when you can edit things as you
| wish [2].
|
| [1] - https://golang.org/ref/mod#go-mod-file-replace
|
| [2] - https://golang.org/ref/mod#vendoring
| hnlmorg wrote:
| That's no different to importing a module in Perl. If you
| want to know what's in that module then you read the
| source of it.
|
| > _I understand all of that. Power_state, display the
| help, power status description etc, but
| prometheus.NewGaugeVec -- great. What is it? Where do I
| find this?_
|
| It's a function in the module `prometheus`:
| "github.com/prometheus/client_golang/prometheus"
|
| It's the same thing as the following Perl code:
| use Prometheus; use Prometheus::Log; use
| Prometheus::Find; use Prometheus::View;
| use vmware::govmomi::vim25::mo; use
| mware::govmomi::vim25::types; my
| %prometheusHostPowerState =
| prometheus::NewGaugeVec(prometheus->GaugeOpts{
| "Namespace" => $namespace, "Subsystem" =>
| "host", "Name" => "power_state",
| "Help" => "poweredOn 1, poweredOff 2, standBy 3, other
| 0", }, @("host_name");
|
| As you can see the code is actually really similar
| between the two languages in that regard. Bare in mind
| I'm not suggesting that the languages themselves are
| similar, eg how modules are created, methods written and
| arrays are handled are clearly different. But the concept
| of reusable imported modules and properties in a
| struct/hash are ostensibly the same.
|
| Disclaimer: I've not written much Perl in the last 3
| years so I might have gotten some of the syntax slightly
| wrong. But it should be close enough for demo purposes.
| doublerabbit wrote:
| Then it would be fair to say I can't grasp the new-modern
| use of github module method then the traditional where
| prometheus.pm exists on disk and I can trace,trap and
| edit on the fly.
|
| With the line above, prometheus::NewGaugeVec. I know it's
| related to the Prometheus module, NewGaurgeVec
| subroutine.
|
| I'm not a programmer, I'm a systems admin who job is to
| take requests of such "we need a vmware exporter, I have
| this. Make it work".
| hnlmorg wrote:
| The "new-modern use of a github module" is the same as
| for Perl. If a module isn't in CPAN you have to manually
| download and place in your project directory. Go just
| does this for you. And the module files in Go are on disk
| -- there's no way you could compile the project if half
| the source code wasn't on disk.
|
| I think you'd probably have enjoyed Go more in the "old"
| days when $GOPATH was required and all modules were
| downloaded into your $GOPATH as it was more explicit were
| modules were and in a way it felt a little more like Perl
| with the file system being a more prominent part of
| modules. This was a very unpopular pattern for developers
| so things have moved on somewhat with modules now being
| pulled into a package directory. Personally I preferred
| the $GOPATH days too but it's fair to say the modules are
| still on disk.
| sleepybrett wrote:
| godoc, same problem with any language that uses any kind
| of modules, you need to consult the documentation for
| that module. https://pkg.go.dev/github.com/prometheus/cli
| ent_golang/prome... .. if fount that by googling `godoc
| prometheus newgaugevec` .. or you could just use `godoc`
|
| Your argument seems to be, "I don't like reading
| documentation." Then by all means don't and write your
| own prometheus metrics module _shrug_
| doublerabbit wrote:
| > Then by all means don't and write your own prometheus
| metrics module shrug
|
| I'm a sysadmin, not a programmer. So I don't code for
| business operations. I compile them to make them work. I
| don't have time to read all the schematics of the
| application to make it work, but when it comes to perl,
| or TCL for that matter. All files are local, if my box
| has air-gapped and no access to github. Then what?
|
| > Your argument seems to be, "I don't like reading
| documentation."
|
| Not at all. I have limited time to spare on
| documentation. It's easier for me to read the code in
| front in practical form then it is to read documentation
| written on some wiki.
| BenTheElder wrote:
| `go mod vendor` will populate all dependency sources into
| `./vendor/` in a modules project for easy grepping.
|
| Some projects still use this to ensure sources work
| airgapped as well.
|
| https://golang.org/cmd/go/#hdr-
| Make_vendored_copy_of_depende...
| preommr wrote:
| > This is one of the most famous straw man arguments made in
| software development and I've seen it used against a plethora
| of different programming languages -- each time completely
| missing the point that you can get bad developers writing bad
| code in any language.
|
| This is a fair point since I wasn't very clear, and I am
| talking about something that's fairly subjective and
| abstract. I think the more claims a language makes, the more
| open it is to failure. I just googled is "rust difficult to
| learn", and the first answer is "no". It's all relative, but
| I am sure that most of us have heard that rust does have a
| steep learning curve. The only other language that I can
| think of that advertises itself as easy is python. And I
| think it has a lot of faults in those claims too. But python
| does a much better job of being easy than go does. It's
| completely different leagues.
|
| Again, this is a messy point to make, either somebody
| understand what I am trying to say or they should leave it at
| that because trying to qualify ideas like this is fuitless.
|
| > I completely disagree. Having fewer keywords does make Go
| simpler to learn and simpler to read other peoples code.
|
| I really don't think skipping keywords like public and using
| casing makes things simpler. A quick google search shows that
| go has 6 less keywords than c. I mean, c'mon...
|
| > I say this based on 30 years of experience writing software
| in more than a dozen different programming languages.
|
| If you've had years of experience in old school c/cpp, then
| (I would assume) go will be a lot easier, and a lot better in
| comparison.
| croes wrote:
| But some languages make it easier to write bad code than
| others.
| hnlmorg wrote:
| > _If you 've had years of experience in old school c/cpp,
| then (I would assume) go will be a lot easier, and a lot
| better in comparison._
|
| In my opinion old school C++ was a lot easier to learn than
| modern C++. I'm talking about the language specification
| specifically. The tooling is undoubtedly better.
|
| Visual Basic 6 easily wins the "easiest language" award in
| my opinion though. But it's often seen as a _faux pas_ to
| mention VB amongst developers
| [deleted]
| jcelerier wrote:
| > Having fewer keywords does make Go simpler to learn and
| simpler to read other peoples code.
|
| that sounds like saying that latin-alphabet languages are
| easier to read than chinese or japanese because they have
| fewer characters. the complexity just goes in the way those
| characters are assembled together.
| gilbetron wrote:
| It would be interesting to find someone that grew up
| knowing a third type of language (no idea what that is,
| though!) and that then learned latin alphabet and chinese
| (say) as an adult and hear what they say :)
| cratermoon wrote:
| Arabic, Hebrew, or one of the Indian subcontinent
| languages.
| autarch wrote:
| Those all use alphabets or syllabaries, so it's just a
| matter of learning a small new set of symbols.
| cratermoon wrote:
| Yes and no. There are complex rules around joining
| letters depending on where they fall in the words. Also
| there are no vowels but sometimes there are vowel
| markers.
| autarch wrote:
| I meant that if you know Hebrew, Arabic, or Hindu,
| learning the Latin alphabet is a lot easier than learning
| Chinese characters. And Latin user will probably find
| Arabic easier than Chinese too, even though the Latin
| alphabet is a bit simpler than Arabic.
| hnlmorg wrote:
| Funny you should use that as an example because one of my
| lockdown projects has been to learn to read simplified
| Chinese and I'd say your point about Latin-alphabet
| languages was also true despite it being intended as a
| falsehood. Learning all the different Hanzi is immensely
| harder because of the number of characters and how
| intricate they often are. I'd also say that last point
| means it's also easier to write Latin characters too.
| jcelerier wrote:
| > Funny you should use that as an example because one of
| my lockdown projects has been to learn to read simplified
| Chinese and I'd say your point about Latin-alphabet
| languages was also true despite it being intended as a
| falsehood.
|
| but that's because you come from a latin background. I
| lived with a japanese girl for a long time and she was
| adamant that kanji were much easier and faster to parse
| for her than western text
| hnlmorg wrote:
| > _but that 's because you come from a latin background.
| I lived with a japanese girl for a long time and she was
| adamant that kanji were much easier and faster to parse
| for her than western text_
|
| You could make your same argument here and say "that's
| because she comes from a Japanese background" ;)
| jcelerier wrote:
| but that is precisely my original argument. in the end
| everyone finds "simple" what they're accustomed to, and
| you end up with more-or-less the same amount of
| complexity overall, no matter the system used to express
| logical thoughts, if you let humans try to optimize it
| over decades (but systematically, for programming
| languages) or generations (but less systematically, for
| spoken languages).
|
| I'm mostly programming in C++ and I find understanding
| what happens in some Python scripts much harder than some
| template metaprograms I've worked on for instance.
| hnlmorg wrote:
| You're conflating different things now: simplicity vs
| familiarity.
|
| If someone is already a C++ guru then writing something
| in C++ for them will be easier than learning Go. But that
| doesn't mean that Go is easier to learn than C++.
|
| When talking about simplicity people generally compare
| all languages as if one has little or no familiarity with
| them. Otherwise it's not a fair comparison.
| jcelerier wrote:
| > You're conflating different things now: simplicity vs
| familiarity.
|
| we're talking about humans, you cannot not conflate them.
|
| > When talking about simplicity people generally compare
| all languages as if one has little or no familiarity with
| them.
|
| that's a philosophically pointless exercice. Things have
| to be assessed in their actual, real-world context to
| bear any relevance !
| hnlmorg wrote:
| ...and you asses something by comparison. Having
| different starting points isn't a comparison, it's a
| bias. I don't have an issue with people having a bias (we
| all have our own preferences, our own strengths and
| weaknesses, and stuff we just enjoy more than other
| stuff). But lets not pretend it's anything more than a
| bias if you're not willing to compare things from an even
| starting point.
| alisonatwork wrote:
| I can see some kind of argument that logograms are easier
| to parse than an alphabet because you can communicate
| more information in a smaller space, but that's only true
| if you already committed the thousands (!) of logograms
| to memory in the first place. This is no trivial task!
|
| The question is if it's worth putting a 5+ year barrier
| in front of people in order to become fluent in a written
| language that maybe, possibly, might be "faster" once you
| are fluent. For native speakers, perhaps that's worth the
| effort (although there are plenty who argue otherwise).
| For second-language speakers, I think the answer is
| almost certainly no.
|
| So bringing it back to Go. Perhaps Go seems more
| difficult and slow to people who already invested the
| years required to become fluent with something like C++.
| I doubt that, but I guess it's possible. But Go isn't
| designed for that case. It's designed as a second
| language that any programmer can learn quickly and become
| reasonably productive in.
|
| If you have a company with 1000 programmers who all know
| different languages, and you want to start creating good
| software right now, would you standardize on the language
| that all 1000 programmers can learn in a couple of weeks,
| or the language that 100 programmers know inside out and
| the other 900 are going to spend a year figuring out?
| turtlebits wrote:
| Part of the hard part in learning Chinese and Japanese is
| that there is a separate phoenetic "alphabet" you have to
| learn to properly pronounce characters. (at least in
| Taiwan, kids learn bopofomo)
| blacksmith_tb wrote:
| I took a year of Mandarin as an undergrad, and learned
| ~1,500 characters (at my best). The two approaches are
| just radically different (pun intended), with an
| alphabetic writing system (not just Latin, but Arabic,
| Cyrillic, etc.) if you know the system, you can read
| texts in other languages that share that system aloud -
| without knowing what you're saying. With logographic
| systems like Hanzi, you may be able to guess at the
| meaning of a character you don't know by looking at its
| radical, but you have no idea how to pronounce it. I do
| think broadly speaking alphabets are easier to teach and
| to learn, though still not easy (ask any small child).
| CobrastanJorji wrote:
| Can I derail this to ask how you've been going about your
| project? I had the same lockdown project but with
| Japanese. It's been going well. I've found a little
| company called Wanikani that does a great implementation
| of a spaced repetition system. I've never rigorously used
| one before, but based on my progress, I'm now a believer
| in the technique and am a bit mad at myself for not doing
| this for school subjects as a kid.
| derefr wrote:
| The argument may be wrong, but the conclusion _is_ true:
| literacy rates _are_ actually lower in countries with
| ideographic languages -- likely because there are more
| properties of words in ideographic languages that need to
| be memorized "literally", and fewer properties that can be
| intuited, or easily "sketched" verbally in order to ask the
| real spelling/pronunciation/etc.
|
| One study I recall (on my phone now, will cite later)
| reported that fewer 20-year-olds have "fluent" levels of
| reading comprehension for what they read in the
| [ideographic] newspaper in Japan or China, than in
| neighbouring countries with alphabetic languages derived
| from those same historical ideographic roots (Korea,
| Vietnam, Thailand.)
|
| Another study (will cite later) reported that the reading-
| comprehension rate for ideograph-heavy works in Japan is
| also _decreasing_ over time, as more people spend their
| time reading mostly explicit "[ideograph-]light" novels,
| rather than literature that would actually teach them
| kanji. (Which is a vicious cycle.)
|
| Given that ideograph radicals are _kind of_ analogous to
| alphabetic morphemes, this is kind of surprising. I think
| it 's mostly because it's self-evident how to pronounce
| alphabetic morphemes if you know the pronunciation rules of
| the language, while
|
| 1. the names for ideographic radicals need to be memorized,
| more like the names of alphabetic letters (but with there
| usually being far more radicals in common use per
| ideographic language, than there are letters in an average
| alphabet.) And
|
| 2. ideograms aren't usually linear, but rather structured
| (things above/below/beside things, things _inside_ things,
| things bonded to other things and reduced in the process,
| etc); and there 's no universal cultural fluency for
| speakers of these languages in an _ordering_ system for
| spelling out these radicals. You usually have to _see a
| character written_ before you can truly know how to "spell
| out" its radicals.
|
| Because of these two problems, you can't just look at an
| ideograph you don't know, and casually, conversationally
| spell it out to someone else, _in order to_ ask how it 's
| pronounced / whether you're pronouncing it correctly.
| Unless, that is, you both know the names of all the
| involved radicals, and have a good geometric guess for the
| ordering. In practice, most people don't try to ask this
| question verbally, but either need to show someone the
| character written; or need to use a dictionary.
|
| I've noticed that this actually results in distinct
| approaches to how people treat "literature with words they
| don't know", between people whose first language is an
| alphabetic one vs. people whose first language is an
| alphabetic one. Given an _alphabetic-language_ work with
| word they don 't know, alphabetic-native people seem to be
| much more confident in just jumping in and looking words up
| as they go; while ideographic-native people seem to be more
| reticent. I _believe_ they 're subconsciously expecting new
| [alphabetic] words to be a much larger barrier for them
| than they actually would be, as they're used to thinking in
| terms of the barrier that novel ideographs impose.
| anthk wrote:
| IDK why do they downvote you; the issues with logographic
| languages are evident. With Spanish for example, you have
| a very regular spelling plus far fewer symbols. You can
| guess the spelling of the word by just reading it, and
| the opposite it's true. You may transpose a b/v, or omit
| an h, but that's it.
| yorwba wrote:
| > literacy rates are actually lower in countries with
| ideographic languages
|
| The World Bank puts China (97%) behind Korea (98%), but
| ahead of Vietnam (95%) and Thailand (94%). They don't
| have data on Japan, but I'd be surprised if their
| literacy rate were much lower. (I'm also on my phone, but
| here's the link: https://data.worldbank.org/indicator/SE.
| ADT.LITR.ZS?location... )
|
| I think those literacy rates mostly reflect the quality
| of these countries' respective education systems, rather
| than any inherent properties of the scripts used.
| TheDong wrote:
| > Having fewer keywords does make Go simpler to learn and
| simpler to read other peoples code
|
| Go carefully touts how few reserved keywords it has, but I
| think it would actually be a simpler to reason about language
| if it had more reserved keywords.
|
| For example, you may notice that "true", "false", "len",
| "new", etc all aren't reserved keywords.
|
| This sometimes does lead to bugs, for example someone may
| make a function, like "func memoize(new func(...interface{})
| interface{}) func(...interface{}) interface{}", which shadows
| a common builtin function with a function argument.
|
| Usually, the above leads to a compiler error when you try to
| use the "copy" argument (a value) as a function, but every
| once in a while, you end up with a type-compatible shadow, at
| which point things can really break.
|
| It would be less confusing if things like "new", "len",
| "copy", and "true" were keywords, rather than builtins that
| someone may accidentally alias and shadow.
|
| If you account for things like rather essential builtins as
| well, go's list of keywords starts to look far less
| impressive, and on-par with java or C#.
| gher-shyu3i wrote:
| true := false is valid golang code
| makapuf wrote:
| Indeed https://play.golang.org/p/-HvoqUjiE6s
| colejohnson66 wrote:
| Speaking of reserved words, I remember reading once about
| how PL/I had _no_ reserved words. Which has the nice quirk
| that this is valid code: IF IF = THEN
| THEN THEN = ELSE ELSE ELSE = ENDIF ENDIF
|
| ...assuming IF, THEN, ELSE, and ENDIF are all variables.
| throwaway894345 wrote:
| > If anybody wants to learn go, ignore everything about how
| easy it is to learn. Because it's extremely deceptive. Take
| time to actually read through a lot of the important underlying
| concepts like how slices work.
|
| What is your standard for "simple" if learning how to use
| slices is complex? Go slices are just windows into contiguous
| blocks of memory. There are pitfalls--if you have two
| juxtaposed slices backed by the same contiguous block of
| memory, growing the former will write over the latter, but you
| quickly learn that you should virtually never be appending to
| slices that don't have sole ownership over their backing
| memory. Probably the worst part is that there aren't higher-
| level functions for prepending or deleting an item, so you have
| to build them yourself with append, copy, etc primitives (but
| even this has the nice property of exposing the cost of these
| operations, e.g., deleting from the middle of a slice is
| expensive and your average Pythonista probably doesn't
| understand this).
|
| > Ignore comments about how go is simple to write. There's a
| fair amount of bad go code and people break rules all the time.
| From official sdks to standard libs. Go can be extremely
| difficult to both write and read.
|
| This hasn't been my experience.
|
| > implicit interfaces
|
| I love structural sub typing ("implicit interfaces")--I can
| define an interface for a third party type which in a nominally
| subtyped language would require wrapping the third party type
| in a new type whose only purpose is to express the suitability
| of a particular interface. And for no real gain at all (or at
| least I've never felt myself wanting nominal subtyping; perhaps
| it's a difference in workflow).
|
| > judicious abuse of interface{}
|
| Putting aside the contradiction of "judicious abuse", I don't
| think `interface{}` is very common in Go, and where it exists
| it's usually appropriate, for example, JSON de/serialization or
| Printf. `interface{}` is used very sparingly in Go, and
| considering that people build real, successful applications in
| languages like Python and JavaScript where everything is an
| `interface{}`, Go's use isn't that bad.
|
| > Writing go can be difficult because of a lack of some
| language constructs that leave you unsure how to proceed.
|
| I particularly disagree here as well. There's often one way to
| do something in Go, and I've had very good luck by Googling
| "How to do x in Go?".
|
| > OTOH, things like criticisms about it's error handling are
| overblown. At best it's a mild nuisance, and more often than
| not, a good thing that makes error handling explicit and clear.
|
| Agree here. Maybe I'm an unusually fast typer, but the majority
| of criticisms seem to be about how long it takes people to type
| out the `if err != nil {` boilerplate.
|
| Personally my biggest criticism of Go is the lack of sum types
| (IMO I would much prefer sum types to generics). There are a
| lot of cases where it would be nice to express OR constraints.
| There are workarounds in Go--for example, using an interface
| with a private method that the variants must implement, but
| that's a lot of error-prone boilerplate and it tends to result
| in unnecessary allocations and dynamic dispatch (as opposed to
| a switch statement).
|
| Another criticism is that the compiler doesn't optimize as
| aggressively as I would like, including that many abstractions
| are runtime abstractions that could be compile-time
| abstractions (specifically, Go doesn't have semantics for
| distinguishing between a run- and compile-time abstractions and
| the compiler pretty much always assumes that all abstractions
| are runtime abstractions.
|
| > If you can, use goland. I use vscode and it's... not pretty.
| Almost every single thread I've seen on reddit recommends
| goland. My experience with vscode has been very unpleasant,
| particularly with go plus.
|
| I've been pretty happy with vim. I haven't used goland. vscode
| became noticeably worse around the time that modules landed,
| and IMO never fully recovered. `gopls` has also been
| disappointing. Go's editor story used to be best in class in
| general, but it seems to have gone downhill. Still, I think
| it's well above average (especially with respect to the
| dynamically typed languages).
| everybodyknows wrote:
| >if you have two juxtaposed slices backed by the same
| contiguous block of memory, growing the former will write
| over the latter, but you quickly learn that you should
| virtually never be appending to slices that don't have sole
| ownership over their backing memory.
|
| You also may have to learn the hard way that saving a pointer
| to an entry of a slice that is later appended to may, or may
| not, depending on len()<cap(), produce an unintended copy.
|
| >I particularly disagree here as well. There's often one way
| to do something in Go, and I've had very good luck by
| Googling "How to do x in Go?".
|
| How about deciding whether a heavily-used pure-function
| method should take a whole struct as its receiver, or instead
| a pointer to it?
|
| If a whole struct, then non-modification of the receiver is
| guaranteed by the compiler, a great boon to the code
| maintainer.
|
| If a pointer, then any number of members may be added to the
| struct with no performance penalty per invocation.
|
| How to choose?
| throwaway894345 wrote:
| > How about deciding whether a heavily-used pure-function
| method should take a whole struct as its receiver, or
| instead a pointer to it? If a whole struct, then non-
| modification of the receiver is guaranteed by the compiler,
| a great boon to the code maintainer. If a pointer, then any
| number of members may be added to the struct with no
| performance penalty per invocation. How to choose?
|
| It seems like you answered your own question. I'm not
| really sure what you're looking for here...
|
| > You also may have to learn the hard way that saving a
| pointer to an entry of a slice that is later appended to
| may, or may not, depending on len()<cap(), produce an
| unintended copy.
|
| That's all pretty inductive from the simple definition of a
| slice: a growable view into a backing array (where "grow"
| implies copying to a new, larger backing array). But yes,
| it can be surprising if you are jumping into Go without
| ever reading the basics. In general, the best practice is
| to avoid multiple references into a mutable slice (this
| seems like generally good advice in any language).
| Philip-J-Fry wrote:
| In my experience, Go is as simple as you make it and it is easy
| to learn. You can cover the whole language in a few hours. With
| anything that simplifies interacting with the underlying
| hardware there will be complexity hidden away from you. That's
| inevitable. Go is no different to any other language in that
| regard.
|
| The hardest part of Go is learning how to effectively use
| things like goroutines and channels.
|
| Slices might catch some noobs out, but at the end of the day
| it's as simple as saying "a slice is a view on a block of
| memory", so 2 slices can point at the same data, and changing
| data with 1 slice can be reflected in the other. Once you
| realise that a slice doesn't hold values there's no issues.
| That's simple, I just explained slices in 5 seconds.
|
| I think implicit interfaces are amazing. Yes it can be hard to
| figure out what implements it, but an IDE is used for that.
| Like you say, Goland is really good. Abuse of interface{} is
| bad, it's the worse decision that was ever made for the
| language in my opinion. But I don't think it's that big of a
| deal in the grand scheme of things. Generics will remove a lot
| of it's current uses anyway. I write microservices and the only
| time I have to touch interface{} is when using contexts.
|
| It's not for everyone, but people saying "Go isn't simple" are
| just as bad. You've got to understand people from all sorts of
| backgrounds have learned Go. For me, I really think it's easy
| to learn and simple to use. Others might think it's the hardest
| thing they've ever done.
| gher-shyu3i wrote:
| > Yes it can be hard to figure out what implements it, but an
| IDE is used for that.
|
| Which is ironic given that the golang designers and users
| tend to shun IDEs and mock that languages like Java rely on
| them. When in fact, to do anything useful in golang you also
| need an IDE.
| shp0ngle wrote:
| Ahhh Context.
|
| For me, using context and stuffing and retrieving things from
| it is the most painful part of go.
|
| If anything from go should die in a fire, it's Context -
| well, the key value storage anyway. The canceling part is
| fine.
| Philip-J-Fry wrote:
| Context is really good so long as what you're storing
| deserves to be there. For example, any UUIDs you generate
| for request tracing or anything like that. Once you start
| storing actual request data like users, or session data,
| etc. then it's a problem.
|
| I'm of the opinion that (if you're writing web services)
| anything related to the request should just be passed to
| the function using it. Shouldn't be stored on context and
| passed along 20 middleware handlers. If you need to share
| state this way then it's a failure of your design. Putting
| the meat of your business logic in multiple handlers is not
| the way. A handler is how you get the data into your
| application, then you can forget about them. But some
| people don't really understand that and start having
| authentication middleware, session middleware, user
| middleware etc. Just pointless complexity.
| henvic wrote:
| For you the problem is the very fact you're able to pass
| values through context transparently or that some people
| abuse it passing all sort of data that should be passed in
| better ways?
| scottlawson wrote:
| I think it would be a more productive discussion to ask whether
| go is a simpler language (compared to popular alternatives),
| not whether it is simple in an absolute sense.
|
| Given how complex computers and programming is, it's easy to
| argue that any language is not simple.
|
| It's a more interesting question to ask which of the languages
| is simplest.
___________________________________________________________________
(page generated 2021-03-22 23:02 UTC)