16 ms·
Go with generics has definitely surpassed Python for me. Python is good for prototyping but the package management story and the "feel" of the language has ruin
by 1_player 5y ago
Go with generics has definitely surpassed Python for me. Python is good for prototyping but the package management story and the "feel" of the language has ruined it for me. I used to love Python, until I used Django professionally, and the façade crumbled. I'm done with OOP and dynamic typing.
Go felt good, a bit verbose, but my issue was that map/reduce/filter are a much better abstraction over imperative loops, and with generics, the dream of Go with more functional and high-level concepts is closer.
This comment is going to be very controversial, so let me remind you this is my very own opinion.
- Cthulhu_ 5y agoNote that you still shouldn't use Go as a functional language (using map/reduce/filter); it's not optimized for functional programming, and the syntax would be pretty gnarly. A for-loop has what's called "mechanical sympathy", and will go through things in the order that it is in memory. It'll allow the compiler and runtime to manage things quickly through memory, CPU registers, and CPU pipelines. A great post on the subject is "Why Go Getting Generics Will Not Change Idiomatic Go": http://www.jerf.org/iri/post/2955 http://www.jerf.org/iri/post/2955
- lucian1900 5y agoThe bit about "mechanical sympathy" is wrong, though. Plenty of languages inline map/reduce or iterator type code down to very efficient cache-friendly traversal of memory, most notably Rust. Go's compiler is just particularly naive.
- mananaysiempre 5y ago(The key phrase is “stream fusion”.)
- kortex 5y agoActually I think while the compiler is a bit naive, the compiler writers are not. They are striving for simplicity, maintainability, speed, etc., vs trying to optimize high-level FP-esque idioms into fast machine code. The compiler has definitely gotten more optimal over the years, but it's a different beastie than the rust one. Because go is not rust.
- lucian1900 5y agoGo is not Rust, but there is a lot it could learn from Rust without sacrifice: sum types, Result for error handling, iterators with for loop support, [edit] non-nullable types etc.
- sacado2 5y agoNot as simple as it seems. For instance, what is the zero value of a sum type? Let's say, the zero value of a Result<int, error>?
- kortex 5y agoPerfect example of a caveat to "without sacrifice". For context, go really cares about having "zero values" - every initialized variable of some type must have a zero value. The zero of Error is nil, so logically this would be Result(0, nil). But what do you set the internal state? It's not Ok, cause that int isn't used, and it's not Err either. Option would work fine though and it would be amazing to map over options instead of nil checks. I think you'd need to build Result on top of Option, it's naturally kind of ternary - "I have value" "I have error" "idk", either internally or externally. What might be awesome would be if the Error were a slice type, nil would be "uninitialized" and empty slice means "initialized". still not...pleasant.
- DylanSp 5y agoZero values are definitely an issue, and it'd be hard to get rid of them while sticking to Go's imperative/statement-based style. Still, it'd nice to use an Option type instead of pointers.
- Lev1a 5y agoIIRC in Rust it has to be either of the Ok or Err variants and the enclosed type can then provide its own "zero value" via the standard library "Default" [0] trait or your own implementation for the particular type. That trait is also implemented not for "Result" but for "Option" giving it a default value of "None". [0]: https://doc.rust-lang.org/std/default/trait.Default.html https://doc.rust-lang.org/std/default/trait.Default.html
- fsdjkflsjfsoij 5y ago> Plenty of languages inline map/reduce or iterator type code down to very efficient cache-friendly traversal of memory Very few languages outside of Rust and Haskell actually do this reliably and that's including languages like Ocaml and F#. Rust and Haskell are certainly the only even remotely popular languages that do it.
- spekcular 5y agoDoes Haskell actually succeed here? This is perhaps not the right way to measure, but: When I last checked the programming language benchmark game [0], the Haskell submissions were basically as fast as C/C++/Rust. But, this came at the cost of writing non-idiomatically/non-functionally – essentially abusing the language to write C in Haskell. I would be curious how well "idiomatic" Haskell compares to C++/Rust, in terms of the compiler optimizing away the functional abstractions. [0] https://benchmarksgame-team.pages.debian.net/benchmarksgame/index.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
- igouy 5y agoThe benchmarks game isn't limited to one Haskell program per task. Look at both https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/spectralnorm-ghc-4.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/... and https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/spectralnorm-ghc-2.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
- spekcular 5y agoThanks, that's pretty convincing.
- nine_k 5y agoDoes the elephant-in-the-room of C++ do it? I thought it does. I can't bet on what Java and JavaScript JITs make of map / forEach / filter / reduce, but I suspect that they can be pretty efficient, given the clear delineation and the repeated patterns.
- deleted 5y ago[deleted]
- kortex 5y agoI love python, and I don't blame you. I can't stand the Django way of doing things. Everything is so opinionated, dynamic, and magical in the bad way. Pytest has a similar vibe and it drives me nuts. Not a fan of OOP, either, I much prefer immutable objects that are either pure data, or convenience methods that return a copy. No more setters, state mutation methods, setattr, unless it's deeply abstracted away. Nowadays I use Fastapi, pydantic, Result, and static typing everywhere. Protocol interfaces are great.
- gautamdivgi 5y agoThis!!! I’ve done a fair bit of python api development mostly for ML services. We used flask/gunicorn and I’m considering moving to fastapi. I’m sure Django is awesome for what it does well but python has a lot more options. Fwiw - I do dabble in Go. I’ve used it for some very targeted systems work where I don’t have to install a python interpreter on the target machine and hacking some k8s operators. I really like Go - but the ML ecosystem is pretty heavily python.
- kortex 5y ago> We used flask/gunicorn and I’m considering moving to fastapi. Do it, do it nao! And by that, I mean at your earliest convenience. It's such a step up from Flask. All the serde is handled for you via Pydantic. No more manually vetting data. Just write constraints.
- maccard 5y agoI want to second this. With quick compile times, fat binaries and first class support for crosd compiling, go is suitable for pretty much everything python would be used for. My only use cases for python are as a replacement to bash for shell scripting.
- kortex 5y agoEh, not really in the data wrangling and machine learning space, at least not quite yet. It's not really amenable to writing libraries for numerical processing - it ends up being super tedious to write something like numpy (you have to implement for every data type, there's at least a dozen+) and nigh-impossible to write an API like pandas, because dataframes are just too dynamic. You could do these things, but it's just super unpleasant. I'm hoping generics makes it easier to write things like numpy, without doing `meao_u8`, `mean_u16` etc. + there's bool, int/uint8,16,32,64, float32/64, complex64/128, that's 13 right there, plus object, a bunch of extended sizes on some architectures, and c-alias types.
- maccard 5y agoThat's a fair point - I don't work in the analysis or ml spave so have no understanding of it!
- travisd 5y agoOther people point out ML is a use case where Go isn't suitable. And I agree. But as someone who used to write a LOT of Python, Go has replaced it for anything service or business-logic oriented, and while I do very little data wrangling and machine learning, Julia would be my go to for that. Julia and Go are in, many ways, complementary opposites. If you need to use PyTorch/TensorFlow, okay, fine Python (I'm not going to seriously advocate for just wrapping it all in PyCall.jl unless it's just incidental usage), but Julia is a really strong language for this stuff nowadays.
- deepsun 5y ago> Package management Are you seriously saying that github.com/somelib is a better package management? Of course nobody forces to use that, but it's what actually been used in most go projects. Even NPM looks better in comparison. The best quality package management I've seen is Maven, followed by Cargo.
- hellcow 5y agoGo has had built-in package management for a while now. It's extremely fast and generates reproducible builds effortlessly in its default behavior in a way I've not experienced before from any other tool.
- angryfeller 5y agonpm is just another layer on top of git. go uses git directly. how is that any worse?
- cris-ward 5y agoFrom someone who briefly used 'bower', which was JS dependency management using git, relying on git is a lot worse. Github repos can vanish, NPM will only let repos be deleted if they have no direct dependencies also on NPM. So you have some guarantees your dependencies wont vanish.
- saturn_vk 5y agoIf the repo was used at least once, it will be cached by the default proxy. At that point, deleting it will have no effect on builds
- ernst_klim 5y agoDoes go have some intermediate cache repository between github and enduser?
- uluyol 5y agoYes, https://proxy.golang.org/ https://proxy.golang.org/ You can also configure go to use your own for internal projects or if you just want to avoid the global proxy.
- pjmlp 5y agoSorry to break it to you, interfaces are OOP and trace back to Objective-C and Common Lisp Object System protocols or BETA patterns.
- pierrebai 5y agoThat is a strange sentiment, based on the reasons you've given. Package management on Python with pipenv or poetry have not been an issue in my experience. The other half is kinda hard to pinpoint since "feel" doesn't say much, but is surprising given how clear and powerful the syntax is. I've also taken to use type annotation in Python to ease some of the typing obscurantism of pure dynamic typing. And python does have map / reduce and much more... so I'm not sure what you mean there. OTOH, I feel Go and Python are mostly used in quite different domains. To me, Python is the new bash. Go is more for those who dislike C++ and Rust (or Haskell or...) and prefer a certain kind of simplicity.
- anyfactor 5y agoIf you don't like Django then you should really try out Flask. It is everything that is right which is wrong about Django and vice versa.
- rirze 5y agofwiw, I think your experience speaks more to Djanjo and other OOP-inspired packages. Python allows for many different styles of packages to be written... and it's not always a good feature to have.
- throwaway894345 5y agoI like Python the language just fine. Static typing needs a good bit of work, but the real pain points for me have always been performance and tooling (especially package management). But Go has solid answers for these problems and an excellent static typing story (generics are gravy, but sum types would be nice). I’ve been very happy with Go on balance.
- metaltyphoon 5y agoExcept when you need to use struct tags, then everything is flimsy. I would rather have C#'s attribute over strings only.
- throwaway894345 5y agoI haven’t had any problem with struct tags personally. I wish Python had some sane way to reliably auto marshal objects to JSON in the stdlib.
- duffsdevice 5y agoI have also left Python for projects where I can chose the tools, but I have not stuck with Go. I went to Racket which has much like Python a "Batteries included" feeling, it is a very easy language with a lot of power and a really good JIT compiler. For me, it is perfect for exploration and algorithm design. For example, I could develop an algorithm in Racket and easily port it to C++11 which was what the client / employer ultimately wanted - still having a much quicker total development time. For things that are performance-critical or require high reliability, I have successfully used Rust, even if I am still much slower writing it. One thing I like is that the resulting code is not more verbose. Which also means that it is easy to read even after months of not touching it.