4 ms·
> Generics will be helpful for some, I'm sure, but my reading of the winds is that people will find other idiosyncracies of Go to latch onto and complain about.
by throwaway894345 5y ago
> Generics will be helpful for some, I'm sure, but my reading of the winds is that people will find other idiosyncracies of Go to latch onto and complain about. It seems to me the next object of hatred is the lack of sum types.
I'm a big Go proponent, and I'm pretty "meh" on generics. They'll make some code easier to read and write, but they'll make a lot of code a lot harder to read (because contrary to popular belief, "readability" doesn't always increase with abstraction or terseness).
That said, sum types would genuinely be helpful--the workarounds are error prone (making sure all cases are handled by code) and inefficient (unnecessary allocations if the implementation is backed by interfaces or wasted memory if it's struct with a field per variant). Note that simply supporting sum types doesn't guarantee that they'll be implemented efficiently--I'm afraid of the possibility that the Go community might settle for an interface-based implementation rather than a union-based implementation.
On balance, however, Go is still the most productive language I've ever used (and by a healthy margin). People make way too big a deal about type system minutia (having a basic type system is important, but going too far beyond that can be counterproductive) and they are far too forgiving for things like bad tooling, poor performance, or impoverished standard libaries.
- djbusby 5y agoWhat do you build where you see that "healthy margin"? I build mostly webApp, and API services (boring business stuff). Reaching for Go or PHP is about the same (read JSON, business rules, database). For this stuff PHP was hardly better than CGI-Perl - except for application performance - where PHP was better than CGI and Go is better than both. What am I missing in using the tools that I don't see that margin? Maybe I'm measuring the wrong thing?
- rob74 5y agoComparing Go and PHP, as a compiled language Go's performance is undeniably better. Plus it has a cleaner design without all the cruft that accumulated in PHP over the decades (in PHP's favor however, you have utility functions that make it really easy to accomplish basic tasks, such as `json_decode` and `file_get_contents`, which are not so straightforward in Go). One example I'm currently confronted with: I'm writing a long-running backend task in PHP, and since the rest of the backend is based on Laravel, it's using Laravel too. The script doesn't really do much, and as far as I can see there should be no memory leaks, but unfortunately it can still only run for ~ 3 hours before it quits because of running out of memory. I'm sure it will be real fun debugging that. Makes me want to switch to Go...
- djbusby 5y agoUsed xdebug profiler, right?
- eacafdcbac 5y agoI've only worked in PHP once, in college, so take the following with whatever level of credibility you wish. I generally work in infosec related projects that often come at strange intersections, such as embedded systems and web applications or real time operating systems in safety critical situations which must deal with data from unreliable or weakly secured sources (802.11, LoRa etc.) So, mostly my experience with Go is the need to write one-off tools, which usually provide either a CLI or web-ui, to inspect things embedded devices are doing as a sort of "black box." I'm sure generics are going to be useful in some instances. Also of note 1.18 is bringing built in fuzzing, which is nice. Where I'm getting my margin of benefit over writing tooling in say Python or Ruby, or other languages that fit this domain: 1. Fewer choices: The build system, module layout, and networking APIs don't lead me down the road of trying to figure out which library is best, thereby wasting time learning different libraries. I have never had any desire to google around for external libraries etc. Everything seems to just work fine. 2. Clear design intent: Once you've figured out what you're supposed to do with language idioms, like passing around ReadClosers or whatever it becomes super easy to read code written by other people who've also come to understand the intent. I don't notice this until I try to go back to doing something in Python and remember how vastly many approaches folks take to the same problem (like how should a database object be passed around.) 3. Works for my workflow: I spend most of my life in terminals fussing with serial communication, or fighting with mqtt or an APK that won't load like I expect, etc. The tooling with Go for nvim is incredible. I've found that now that I've gotten fairly fluent in the language I will often crack off small scripts in Go to automate dumb things I don't want to do in Bash or whatever, this is maybe an anti-pattern, depending on who you talk to. Summary: My big margin over other languages just comes from consistency of design and interfaces and the fact that Go integrates with my workflow. It's very easy to figure out how to do a thing the first time I'm working on it. It's also easy to throw together a one off tool in an afternoon, use it for two weeks, push it up to my github and forget I did it until the next time I need it. YMMV
- matwood 5y ago> I've found that now that I've gotten fairly fluent in the language I will often crack off small scripts in Go to automate dumb things I don't want to do in Bash or whatever, this is maybe an anti-pattern, depending on who you talk to. I do the same. Most everything you need for quick scripting against services and the like is built in. No hunting down libraries. Then the build output is a fully contained binary that can run on my m1 mac, x86 server, whatever. > It's also easy to throw together a one off tool in an afternoon, use it for two weeks, push it up to my github and forget I did it until the next time I need it. And when you do go back to it, the code is easy to read and understand.
- throwaway894345 5y agoIt's entirely possible that for your purposes, Go doesn't yield much of a benefit. I see that "healthy margin" fall out of a bunch of different aspects rather than one big aspect: 1. Working with basic static type support helps me to not worry about silly errors which helps me move faster. Beyond that, it helps team members understand each other's code correctly--when working with dynamically typed languages, type documentation would often be incomplete or become outdated/incorrect and I would spend a lot of time trying to understand the correct type. Moreover, static typing enables a lot of IDE tools that save a ton of time (e.g., goto definition). This is probably more of an advantage for more complex applications rather than simpler CRUD apps. 2. Performance. I've worked on a lot of Python projects where we've spent a lot of time optimizing, and all of the options for optimizing Python have hidden pitfalls (e.g., typically "just rewrite the slow parts to use multiprocessing/C/etc" end up slowing your program down because the costs of marshaling data exceed the gains never mind the costs of maintaining that code). Idiomatic, unoptimized Go is already 10-100X faster than Python and you can pretty easily squeeze more performance out of it via parallelism or moving allocations out of tight loops). If application performance isn't important to you, then this probably won't be particularly compelling. 3. Deployment artifacts. By default, Go compiles to single, reasonably small, static binaries so you can pretty easily build and distribute command line tools to your entire team, you can build tiny Docker images (tiny images mean shorter iteration loop in a cloud environment), etc. 4. Simpler Docker development workflow. With dynamic languages, there's not a great way to iterate. Normally, you'd want to mount your development directory in a volume, but Docker Desktop (or whatever it's called these days) will eat all available CPU marshaling file system events across the VM guest/host boundary, so you end up having to do increasingly convoluted things. 5. Employing and onboarding. Anyone from any language can be productive in Go in a few hours. No need to restrict your hiring pool to "Go developers". Moreover, for other languages, it's not sufficient to merely know the language, you may also have to know the framework, IDE, build tooling, etc that the team uses. The ramp up time can be significant, and this can be a meaningful problem in an industry where people change teams or even companies after a few months or years. This list is pretty narrowly fixated around dynamic languages because I've done more Python development than I have Java/etc and also because your point of reference is PHP. It's hard to compare Go generally to all other languages.
- 5y ago
- jchw 5y agoSum types and pattern matching would be great, and I think they would be much more useful than generics. Unfortunately, Go lacking generics has become a legitimate meme. An article evangelizing .NET recently popped up here and annoyingly used Go’s slowness to get generics as a legitimate point. I don’t think generics will greatly damage what Go has going for it, but I hope it also doesn’t block the way for better error handling, sum types, and other things that could potentially improve code robustness.
- throwaway894345 5y agoI guess I disagree about the legitimacy of the meme or any point that could be made from Go's "slowness to get generics". The only people who think that generics will be a slam-dunk net benefit for Go are the folks who can't articulate the costs associated with generics. The actual net benefit is so small and the error margins are so wide that it is entirely reasonable that Go didn't rush generics, instead prioritizing larger and more certain gains.
- jchw 5y agoI mean legitimate meme as in, it is a point that is widely assumed true at this point, not as in it is actually accurate in its assessment. I never really thought Go needed generics.
- throwaway894345 5y agoAh, that makes sense.
- jrockway 5y agoI think people are going to go off the rails with functions that abstract over for loops. I see it all the time in Javascript code, where people iterate over an Array multiple times because that's what the API makes easy. For example, say you want to separate a slice into two slices, one that contains matches and one that contains everything else. Right now, you'd just write: var matches, mismatches []whatever for _, x := range xs { if x == condition { matches = append(matches, x) } else { mismatches = append(mismatches, x) } } But soon, people will be golfing that down to: matches := slices.Search(xs, func(x whatever) bool { return x == condition }) mismatches := slices.Search(xs, func(x whatever) bool { return x != condition }) This is twice as slow, but it's less lines so I have a feeling that people will have an uncontrollable desire to use it as often as possible. I hope that my feeling is wrong. (Do note that slices.Search is not a real function yet.)
- TimothyBJacobs 5y agoA common API is something like lodash's `partition` so you don't have to loop over the same Array multiple times: https://lodash.com/docs/#partition https://lodash.com/docs/#partition
- Groxx 5y agoWhile I agree that it'll probably increase, for non-performance-sensitive stuff (or small lists) that doesn't really seem like a problem. And for cases where it is, the answer is the same as it has always been: profile and optimize. Though now it's much easier to make a "matches, mismatches := slices.Split(xs, func(x whatever) bool { return x == condition })" helper, so that improvement even reduces the number of lines further.
- akavi 5y agoGo has multiple return values, so you could instead do: matches, mismatches := slices.Partition(xs, func(x) bool { return x == condition });
- cheriot 5y agoMy experience writing Scala was that there's a modest list of ways people iterate over collections that covers 99.9% of cases. For this example, many languages have a Partition function. matches, mismatches := slices.Partition(xs, func(x whatever) bool { return x == condition })
- deleted 5y ago[deleted]