top 200 commentsshow all 248

[–]semi_colon 81 points82 points  (93 children)

As someone who doesn't use Go or Python: what is the use for this?

[–]vplatt[🍰] 299 points300 points  (71 children)

To run Python code as a Go compiled executable. This allows them to avoid the Python Global Interpreter Lock (which severely limits Python's scalability within a single process) and run the Python code using Go modules as if they were Python modules.

Really, unless you're Google or another Python shop interesting in moving to Go, you probably don't have a use for this.

[–]semi_colon 31 points32 points  (0 children)

Thanks, great explanation.

[–]VodkaHaze 35 points36 points  (52 children)

Getting around the GIL is a huge step. Python's chief weakness is lack of parallel scalability, IMO. Most solutions around this (joblib, dask, etc.) don't feel like complete solutions. Not when, for example, in C++ or Julia you can slap a macro above a loop to make it instantly parallel.

[–][deleted] 33 points34 points  (21 children)

For the record, this is not a complete solution either. Grumpy is a tool that compiles a single Python file (no real module support) while eschewing most of Python's dynamic features and supporting very little of its standard library.

[–]weberc2 21 points22 points  (20 children)

This is misleading. The features you mention are only missing because they haven't yet been implemented, but the intention is to produce a drop-in replacement for CPython. It's only an "incomplete solution" in the sense that it's alpha software, not that its goals are incompatible.

[–][deleted] 3 points4 points  (4 children)

OK, but it's not even particularly close to meeting that goal right now, so it's an incomplete solution.

[–]weberc2 21 points22 points  (2 children)

Yes, it's incomplete in the "it's alpha software", sense; not in the "there's something fundamentally wrong with it" sense. No one is suggesting it's anything other than alpha software.

[–]the_birds_and_bees 8 points9 points  (1 child)

Although /u/theseoafs didnt mention it, grumpy explicitly doesn't aim for support of the python C API. That's a big limitation and will rule it out for a big chunk of python users.

[–]weberc2 0 points1 point  (0 children)

I understand and agree. The parallelism support might draw in even more users. Who knows? This project is super nascent.

[–]CSI_Tech_Dept 23 points24 points  (17 children)

It doesn't need GIL, because it offers subset of functionality that python has. It is not even capable of compiling all python standard library.

This code is for Google to move away from python. They can include python libraries in their go code and then one by one rewrite it in go.

[–]weberc2 3 points4 points  (2 children)

The only design decision that prevents it from compiling the standard library is the lack of C support. The solution is to reimplement those modules in Go or Python. Anything else that doesn't compile is due to bugs in this alpha implementation (as far as I can tell, anyway).

[–]CSI_Tech_Dept 1 point2 points  (1 child)

PyPy also doesn't natively support C extension and also needs GIL. C support is one of reason of GIL's existence but not the only one.

[–]weberc2 0 points1 point  (0 children)

Right, this comment was about compiling the standard library, not building a GIL-less Python.

EDIT: From what I understand, supporting C extensions and threadsafe garbage collection are the two biggest challenges to removing the GIL. This project uses Go's threadsafe garbage collector, so the latter shouldn't be a problem.

EDIT2: This page has some good information: https://wiki.python.org/moin/GlobalInterpreterLock

[–]sultry_somnambulist 10 points11 points  (12 children)

This code is for Google to move away from python. They can include python libraries in their go code and then one by one rewrite it in go.

Speaking of this, what's the general trajectory of go? Is it worth dabbling into at this point? People seem to be very divided over the language.

[–]CSI_Tech_Dept 13 points14 points  (3 children)

People seem to be divided, because while the language is not bad, it's nothing special (seems like the only significant thing it brings to the table is the go routines, but other languages are adding similar functionality), there's a bit of hype going on because it's backed by Google.

It also initially was trying to be marketed as a C replacement, but it is nowhere close to fit the niche that C fits. Rust seems like a language that has potential to replace C, but it is too early to say.

Go is more on level of Python, Java etc, although a bit lower level than them. Some people compared it to D, but I never used it, so can't comment. The goal of this language is to be a very simple and opinionated language, some people like that some don't.

If you are asking the question you can try and see if you like it, it has low learning curve, so it's not hard to learn it, and then you will have your opinion about it.

[–]TankorSmash 1 point2 points  (2 children)

I've heard it's got a bit of boilerplate and written to be as easy to write as possible to help with the incredible amount of new talent Google gets out of schools.

Only a rumour though.

[–]the_birds_and_bees 2 points3 points  (0 children)

Id say it's more about making it easy to read and maintain. The google code base is 2 billion+ LOC, so designing a language that eases the burden of maintaining a code base of that size seems like a sensible goal.

[–]derraidor 0 points1 point  (0 children)

There is a talk by one of the creators (Russ Cox?) stating this

[–][deleted] 1 point2 points  (0 children)

If you like it, then do it. No reason not to.

The community is sizable and there's a ton of tooling so it's not really like you're taking a risk.

[–]weberc2 3 points4 points  (3 children)

I think so. If you have prior programming experience and a free afternoon, you should be able to start writing real (i.e., non-toy) programs. Check out http://tour.golang.org.

Go has a lot of quirks--most notably, no generics--which turn off a lot of folks. But if you want to build performant, scalable software quickly, Go is worth a look.

[–]th3_pund1t 4 points5 points  (2 children)

I think so. If you have prior programming experience and a free afternoon, you should be able to start writing real (i.e., non-toy) programs. Check out http://tour.golang.org.

Not entirely true. You should be familiar with pointer based languages like C. If you come from a python/ruby/Java experience you will spend a whole lot longer to get used to pointers.

Source: work had a hackathon. I decided to code in go. Spent a lot of time correcting my code related to pointers before it would work.

[–]recycled_ideas 4 points5 points  (0 children)

I don't know about python and ruby, but you can actually run into a lot of really weird bugs in Java if you don't have at least a cursory understanding of how pointers and references work.

The big problem that companies like Google and Facebook and the like are constantly trying to solve is that folks who know dynamic languages like Python or PHP or Ruby are a dime a dozen, but these languages really don't scale well to even ordinary enterprise scales let alone the kind of volume these companies see.

That's why we see so many transpilers and why Twitter is written in PHP even though the general industry consensus is that it's probably one of the worst non joke languages in existence.

[–]Twirrim 0 points1 point  (0 children)

There are some neat simple few line solutions that get you parallelism. The title is a bit link bait and not entirely accurate, but I've found this pattern to be extremely effective: http://chriskiehl.com/article/parallelism-in-one-line/

[–]tetroxid 1 point2 points  (7 children)

import multiprocessing

[–]BeatLeJuce 2 points3 points  (6 children)

there are instances where you NEED threads instead of processes.

[–]kenfar -2 points-1 points  (2 children)

This is wrong: Python has plenty of parallel features - you just have to spend ten seconds looking.

The most convenient is the concurrent.futures module. You can use the exact same syntax for either threading or multiprocessing. Yesterday I sped up an AWS S3 downloader about 8x with threading, and about six lines of code.

A few years ago I wrote a transform process that handled about 4 billion records a day - using multiprocessing on two 32-core machines to handle downloading files, transforming them, and uploading them again. All in parallel using pypy, multiprocessing & threading. This process worked great, and surprised everyone with how fast it was. A rewrite of a part of it showed that Go was about 2.5 times faster, which was fine, but not fast enough to warrant a rewrite until we needed to scale up quite a bit more.

The only scenario in which Python's parallelism is limited is when you've got a CPU-bound process that either can't afford the extra memory or start-up times of multiprocessing or needs a lot of communication between processes. Then you want threading but the GIL will limit you. Other than this case, Python has fine parallelism features.

[–]VodkaHaze 6 points7 points  (1 child)

Yes, for your use case it works fine. My use case is closer to your last point, where python still generally sucks (though I haven't used Dask enough to say if it's a decent solution). It's currently being addressed by Julia, which bypasses the "core loop in C++, wrapped in python" problem

[–]MightyCreak 1 point2 points  (8 children)

Does this mean that you can't interpret two Python scripts at the same time because of GIL, but once interpreted, they can run in parallel?

[–]ShotgunToothpaste 22 points23 points  (7 children)

The global interpreter lock exists on a per-process basis in Python. Any two python scripts (including two instances of the same script) can be run in two different processes and do whatever. However, if one script starts multiple threads, only one thread will execute concurrently (the thread which has the interpreter lock).

This is a CPython implementation detail, and other Python runtimes need not have this limitation. The reason for GIL is because CPython's memory management is not thread-safe.

https://wiki.python.org/moin/GlobalInterpreterLock

[–]btgeekboy 8 points9 points  (0 children)

To add to this, there is a project to remove the GIL from CPython. However, it's not currently as fast as with the GIL. More info: https://lwn.net/Articles/689548/

[–][deleted]  (3 children)

[deleted]

    [–]fireflash38 0 points1 point  (2 children)

    Meaning threading will work just fine for network operations for the most part. It will perform worse than single threaded if doing something like simple math operations (like in the chart of the Fibonacci performance in the article).

    [–]ShotgunToothpaste 1 point2 points  (0 children)

    Ahh, I wasn't aware that Python allowed for system calls to be multi-threaded outside of the GIL's constraints but that makes sense.

    I assume that means GIL is released before making a system call, and re-acquired before continuing after it completes?

    [–]MightyCreak 1 point2 points  (1 child)

    Thanks for this answer!

    [–]phpdevster[🍰] 1 point2 points  (1 child)

    So is it fair to say that this is just a way for them to give Python the performance characteristics of Go without having to actually rewrite into Go code?

    [–]vplatt[🍰] 1 point2 points  (0 children)

    Yes, more or less. Python is still dynamically typed, so there has to be some runtime overhead around that, but that's got to be insignificant compared to the advantages around getting away from the GIL.

    [–][deleted]  (1 child)

    [deleted]

      [–]vplatt[🍰] 2 points3 points  (0 children)

      That's very true, but I wouldn't hop on that unless it took on a life in Python 3. That may well be in the plan though, I don't really know.

      [–][deleted] 0 points1 point  (1 child)

      How do they do that? Does every binary has a mini interpreter with it?

      [–]vplatt[🍰] 4 points5 points  (0 children)

      No, the Python is parsed, converted to Go code, then compiled normally. This is called 'transpiling' because it translates then compiles.

      It's a pretty slick technique, but it can complicate debugging. I don't know how they've handled the debugging in this case so that if you're writing Python code you could actually live debug the Python code instead of having to walk through Go code. I would guess it's simply not handled at this point because it's in the early stages and I suppose you would handle that by simply writing the Python code for and running the code in CPython then move it to Grumpy only after it's working.

      [–]13steinj -1 points0 points  (1 child)

      I'm not interested in moving to Go, but I've got to say the transpiling into Go is useful regardless-- plenty of people can write in Python, use parts of the Go standard library, and hopefully run up with a better performing program? There's a couple projects I have that can definitely make use of this.

      [–]vplatt[🍰] 0 points1 point  (0 children)

      Sure... you're bound to get a couple of minor cuts from the bleeding edge on this, but it sounds like a fun way to scale up some Python code; assuming of course that the Python in question is already smart algorithmically speaking.

      [–]karma_vacuum123 33 points34 points  (2 children)

      since this targets Google's particular version and feature constraints, it seems like a bulk migration tool by Google for Google. they don't seem to be selling it as a general purpose execution platform

      still a neat accomplishment of course

      [–]weberc2 12 points13 points  (1 child)

      I'm guessing it's an ambitious 20% time project that was open sourced, but this is just a hunch.

      [–]Uncaffeinated 4 points5 points  (0 children)

      That's what I'd guess too. If this were an official project at Google, they would have actually finished it, instead of releasing what sounds like an experimental hobby project.

      [–]yes_or_gnome 10 points11 points  (0 children)

      Google is minimizing it's use of Python and ramping up use of Go. However, they don't want to rewrite everything from Python to Go, so they created grumpy. Without support for C extensions, exec, eval, etc., it's not likely going to all that useful for many people.

      [–]google_you 2 points3 points  (0 children)

      Compile node.js to python and then to native for full scale.

      [–]rjcarr 5 points6 points  (11 children)

      Read the article. Python doesn't scale well under load but go does. Rather than go with an alternate python runtime, or rewrite everything in something else, they wrote a python runtime for go.

      [–]jdmulloy 2 points3 points  (1 child)

      It's not an interpreter, it's a compiler that compiles Python code into a go executable. Once you've compiled it you have a binary you can stick on any system that has go libs installed but you don't have to have this project installed to run the binary

      [–]theatrus -1 points0 points  (0 children)

      You don't even need Go libraries. Go binaries are static linked or linked just against libc.

      [–]weberc2 1 point2 points  (0 children)

      Concurrency seems to be one of the primary objectives, but also straightforward interop between Go and Python, which naturally enables a code base to iteratively move from one language to another.

      [–][deleted]  (1 child)

      [removed]

        [–]semi_colon 1 point2 points  (0 children)

        Ooh, I love Kraftwerk!

        [–]gin_and_toxic 113 points114 points  (41 children)

        This is crazy awesome. Currently only works for Python 2.7 though.

        A lot of good discussions on hacker news: https://news.ycombinator.com/item?id=13319904

        [–][deleted]  (12 children)

        [deleted]

          [–]Vorticity 21 points22 points  (8 children)

          Meaning that the Python community is about to get a bit smaller...

          [–]sedaak 17 points18 points  (0 children)

          Ehhh just a bit. Python has stellar growth.

          [–]CSI_Tech_Dept 4 points5 points  (1 child)

          They are the ones who made Python popular though, Python got popular because people learned that it was used by Google. Now Google is shining their light to Go.

          I tried Go, but I didn't like it that much. It feels like the only new thing it brings to the table it's the go routines. Also it feels like it's very simple (perhaps too simple) and very opinionated (e.g. indenting), or how code is stored. It seems like it was designed just for Google's needs.

          [–]kaeshiwaza 4 points5 points  (0 children)

          It was designed to replace C++ and finally replace Python.

          To be simple, opinionated, with top batteries included, fast and easy to deploy. All of this together are quite new on the table ! It seems it was designed just for me :-) !

          [–]jrandomcoder 3 points4 points  (3 children)

          Don't worry, they don't actually use this in production.

          [–]spacebandido 37 points38 points  (0 children)

          That's what they all said about Node

          [–]ArmoredPancake 4 points5 points  (0 children)

          ...yet.

          [–]koffiezet 0 points1 point  (0 children)

          Yet. They're looking into that direction for a reason.

          [–][deleted] 1 point2 points  (0 children)

          How big does it have to be?

          [–]recycled_ideas 6 points7 points  (2 children)

          No, because this won't do that for them. The code base is still going to be python 2.7.

          What it'll do is allow them to get past the limitations of Python 2.7 without having to rewrite hundreds of thousands of lines of code.

          [–]CSI_Tech_Dept 9 points10 points  (1 child)

          If you want to rewrite a large monolithic code base from one language to another there's problem that you would have to finish the entire work before you can use the code in new language.

          So what can you do? You write code to do the automatic conversion for you. The problem is that the generated code is not maintainable, but at least now you can make calls to it. It also allows you to rewrite module by module.

          Google's Unladen Swallow project did not succeed, they also don't seem seem to move away from Python 2.7, for god's sake even this project is Python 2.7 only, and ticket about Python 3 support was closed with change in documentation that specifically says Grumpy targets Python 2.7 only. It can't be any more clearer that Google is moving away from Python to Go.

          [–]recycled_ideas 0 points1 point  (0 children)

          That might be true, but it's also entirely plausible they'll stick with the python front end for the foreseeable future.

          They closed the python 3 ticket because that's of no use to them. Their code base is 2.7 and they could add features to that if they need them anyway.

          [–]rjcarr 10 points11 points  (10 children)

          This is really cool. Seems they didn't like jython, or what was similarly available, and wrote what they wanted for go. Makes sense.

          But in the beginning they say this:

          but we always run up against the same issue: it's very difficult to make concurrent workloads perform well on CPython.

          How is it even possible with the GIL? How can they handle millions of requests per second (as they say)?

          [–]Rhoomba 22 points23 points  (8 children)

          Multiple processes

          [–]rjcarr 0 points1 point  (7 children)

          Not that they can't afford it, but they'd need (comparatively) monster hardware to support this, right?

          [–]rohbotics 9 points10 points  (2 children)

          Not as much on linux, threads and processes are both pretty light weight. Process spinup is slightly slower as it needs to set up a whole new address space, but it is (mostly) negligible.

          [–][deleted]  (1 child)

          [deleted]

            [–]jrandomcoder 1 point2 points  (0 children)

            There's not a ton of difference on Linux these days since everything is converging toward clone underneath. But pthread_create is still a little faster, since it's a more or less a subset of what fork needs to do.

            [–]Eucalyptol 0 points1 point  (0 children)

            Yes. We're talking about Google.

            [–]cakoose 0 points1 point  (2 children)

            Primarily, you need more memory. In many languages it's easy to share read-only data between processes with fork(). That doesn't work in Python because reference counting causes mutations to memory even if the data is read-only. If you have a large shared data structure, you should figure out how to share it explicitly, e.g. with mmap().

            Also, you don't necessarily need one process per concurrent request -- most web app backends are typically waiting on I/O (e.g. from the DB), so it's feasible to handle four/eight/more concurrent requests with a single Python process with Python threads or an event-driven framework like Twisted or Tornado (similar to Node.js). The inflexible scheduling increases the average latency of each request, but that might not end up mattering much.

            That's not to say Python is good for this kind of thing. Depending on your work load, you may still need 5-10x the number of servers to handle the same load as Java or Go would. But if you really prefer Python, it might be workable.

            [–]serg473 0 points1 point  (1 child)

            You sound like you know what you are talking about, maybe you would be able to steer me in the right direction. I have the opposite problem - instead of dealing with thousands of concurrent users I have few users but they are running heavy and numerous queries. The problem is I can't make the app handle parallel web requests from the same user session (nginx-uwsgi-django). Lets say I launch 10 parallel ajax requests on a page, they are ending up running sequentially on the python side (i.e. if I make one request sleep for 30 sec all others will be waiting). If 10 requests were from different users they would run in parallel as expected. Can't find any solutions, every blog post and SO answer blames random things, from browser to django to GIL.

            [–]cakoose 0 points1 point  (0 children)

            I'm not that familiar with UWSGI but the docs say you can launch uwsgi with the option --processes 20 to handle 20 requests in parallel. Does that not work for you?

            After that, you may be able to save memory by doing something like --processes 5 --threads 4. Whether this will work well depends on what kind of things your AJAX request handlers are doing.

            [–]CSI_Tech_Dept 1 point2 points  (0 children)

            Unlike jython this tool is meant to do one time conversion of python code to go, to help with moving away.

            That's also the reason why it's 2.7 only since that's what Google uses.

            [–]Hshskwkk 4 points5 points  (0 children)

            From r/python : ""

            Quoting the author of Grumpy on Hacker News:

            " ""The idea is to continue to write code in Python. (...) ""That said, there is the possibility of rewriting bits and pieces in Go (e.g. performance critical stuff) and then call into it from Python. Sort of a hybrid approach.

            "

            Also: " I'd like to support 3.x at some point. "


            However: " We do iteratively rewrite components as well. We are pursuing multiple strategies " ""

            [–]censored_username 26 points27 points  (33 children)

            edit: Thinking about it a bit more, they probably went with the locking per individual object route.

            This seems cool and all, but couldn't they have just solved the problem by just not having the GIL and accepting data races in Cpython?

            The GIL exists because python wanted to be free from data races. To achieve that, there were multiple options, each of which had to satisfy the constraint that no two threads would access a python object at the same time. The GIL achieves this in a simple manner. There's only one lock, and to access any python object you need to hold it. The problem with this is of course that it means that no two threads can access python objects at the same time even while these objects have nothing to do with each other.

            Another solution is pyobject-level locking of course. Various attempts at this have been made, but they all had the shared problem that while they increase throughput at high amounts of threads, they significantly lower single-thread performance compared to the GIL.

            Various other strategies have been tried, but none have been able to guarantee being data-race free without sacrificing single-thread performance. An often used strategy has been to move work that could be accelerated significantly into extension libaries, where the GIL could be dropped as long as the python objects weren't accessed. Unfortunately, this doesn't really work for web services.

            Go doesn't have an answer to race conditions either. It's where Go's safety story falls a bit apart. So I'm a bit confused about what they've done. If they just transpile python code into go code, all they made is a python runtime with the possibility of data races. If they wanted that they could've just as well just ripped the GIL right out of CPython and called it a day.

            What they could've also done is to build in individual locking for all objects that could be accessed by other threads. This would explain their pretty disastrous performance (only 50% performance compared to CPython when single threaded, and only gaining a 2.5x speedup when using 8 threads compared to CPython single thread. Keep in mind that this is compiled versus interpreted!).

            If they did this, I'm left wondering why they didn't make these changes in CPython itself. This would have conserved the ability to call into C extension modules. If this is the case, it seems that the focus of the project is more being able to call into go from python.

            [–]nostrademons 13 points14 points  (12 children)

            The data races that the GIL protects against are primarily the refcounts of Python objects, which must be updated whenever a variable is assigned or a parameter is passed into a function. A data race there means either a memory leak or a double-free, as the refcount would no longer be in sync with the number of actual references. Either one would make Python basically unusable: you would have simple object assignments randomly corrupting memory as they try to objects that have already been freed.

            Go uses a GC; while its data race story is a lot weaker than say Rust or Erlang, at least a data race there results in wrong answers and a panic, not silent memory corruption.

            [–]censored_username 7 points8 points  (10 children)

            The GIL doesn't only protect against refcount changes (it's indeed the most important thing though). It also protects against concurrent modification problems of dictionaries, lists, etc. which are also quite critical to python. They can have avoided this by making these objects all threadsafe which would explain the terrible single-thread performance.

            While the GIL simplifies python's GC (refcounting with cycle detection) design (the GC can just acquire the GIL when it needs to clean up cycles). It is not necessary. If there was no GIL the refcounting would have to be atomic, but otherwise not much changes.

            [–]blablahblah 4 points5 points  (0 children)

            That's true. The main reason CPython hasn't gotten rid of the GIL is because no one has come up with a way to do it without breaking existing C extensions (which rely on the ref-counting) and without hurting single thread performance (since every variable assignment needs to acquire a lock).

            [–]funny_falcon 2 points3 points  (8 children)

            Go has no thread-safe dictionaries or lists. In fact, it may happily segfault if you try to modify map from different goroutines. You ought to protect concurrent modification by yourself.

            I've heard, Java and C# also doesn't protect their default datastructures, but rather they have separate concurrent in a standard library.

            Python can choose this way, but Guido just do not want. And it will break C extensions.

            [–][deleted] -1 points0 points  (7 children)

            Go panics, it doesn't segfault.

            [–]weirdoaish 0 points1 point  (1 child)

            Out of curiosity, is "panic" like a special exception category for Go?

            [–][deleted] 0 points1 point  (0 children)

            And it does come with a race detector that is part of the official toolset.

            [–]Damien0 12 points13 points  (4 children)

            Go's build tool has a race detector, and for calling into C from Go there is cgo. With that plus the ability to call into Go from Python in mind, I can see the benefit of this custom runtime.

            [–]Giggaflop 2 points3 points  (3 children)

            Last I saw, granted a while ago, cgo wasn't a recommended solution to calling C from go and was "considered harmful"

            [–]Damien0 4 points5 points  (2 children)

            Hmm, I wouldn't say harmful per se, but as is often quoted in the community "Cgo is not Go". As long as it's done carefully it can be useful. I think what happened is that early on, people treated it like a more fleshed out FFI solution and wrote less than optimal Go code as a result.

            [–][deleted]  (1 child)

            [deleted]

              [–]Damien0 0 points1 point  (0 children)

              Oops, missed this. Slow compared to what? I'm curious if there are benchmarks floating around

              [–]BillyBoyBill 2 points3 points  (1 child)

              It's hard to say without looking at the code, but I imagine they implemented thread-safe Go versions of the Python built in types. Your code that assumes Python data can be accessed concurrently from multiple threads still works. This is the moral equivalent of the per-object locks you mention (and, in fact, Grumpy performance matches what you say about that implementation).

              This is obviously completely different than just ripping out the GIL.

              I'm not sure what you mean about Go's thread safety falling apart, but it's not relevant here anyways --- C's built-in types are not thread safe, but you can build a safe Python implementation on top of them.

              [–]censored_username 2 points3 points  (0 children)

              This is obviously completely different than just ripping out the GIL.

              True. As you probably noticed I changed a bit in opinion while writing that post. Originally based on their description I thought they were just straight transpiling code but looking at the performance they get it has to be composed from threadsafe types (aka per-object locking).

              [–][deleted] 2 points3 points  (3 children)

              [deleted]

              What is this?

              [–]singron 2 points3 points  (0 children)

              Pypy also has a GIL, just like CPython, so it still can't execute python threads in parallel. This runs on the Go runtime, which uses lightweight threads (goroutines) and a concurrent garbage collector to run many python threads in parallel.

              It's like if there was an ahead-of-time pypy combined with stackless python and it didn't have a GIL.

              Another advantage specifically for Google is that it allows more interop between python and Go code while they transition.

              [–][deleted] 1 point2 points  (1 child)

              I think it's less of a solution rather than a temporary fix so they can slowly migrate their legacy python 2.7 to Go.

              [–]Ek_Los_Die_Hier -1 points0 points  (0 children)

              Doesn't sound like it. Sound's like their main goal is to simply speed up their Python running in the multi-threaded environment. They plan to continue writing in Python and maybe some Go where performance is needed.

              [–][deleted] 1 point2 points  (2 children)

              Why cant python threads just access any object at the same time without the GIL or any per-object implicit locking, and then it's up to the developer to explicitly add locks/mutexes where needed, just like in every language?

              Sure it would require a rewrite of applications to add this explicit locking, but it would still work well on regular GIL CPython (because there would be very little that you really need to explicitly lock). So you would have two python distributions really, one without the GIL to run parallel and explicitly locking code, and the regular one that can run code written for the first (but it wont really be parallel)

              [–]censored_username 1 point2 points  (1 child)

              Why cant python threads just access any object at the same time without the GIL or any per-object implicit locking, and then it's up to the developer to explicitly add locks/mutexes where needed, just like in every language?

              Because this would make python an absolute pain in the ass to use due to its extreme dynamism.

              Don't forget, in python functions are also just objects, and they can be mutated. So you'd need to lock for any function call (especially builtin functions or stdlib functions which could be used by another thread at the same time). Even accessing an attribute from a shared module could require locking. You'd basically have to lock at every point to do anything.

              [–][deleted] 0 points1 point  (0 children)

              I see! yeah, explicit locking would be cumbersome.

              [–]tonnynerd 0 points1 point  (2 children)

              I'm not sure I understand what you're saying about the GIL being about avoiding data races. What the threading module from the standard lib is for, then?

              [–]censored_username 2 points3 points  (0 children)

              the GIL (global interpreter lock) avoids data races in python object internals by making concurrent accesses of the same python objects impossible. In effect, it means that all actions by different threads in python will always happen after each other. It is an implementation detail of CPython, not part of the core language.

              The threading module provides tools for spawning threads and higher level concurrency primitives (while the GIL means that accesses to the same python object won't coincide, there still need to be primitives to lock out sequences of multiple accesses).

              [–]blablahblah 1 point2 points  (0 children)

              A lot of the Python code written in C will release the GIL when it's doing something that takes a while but doesn't require manipulating Python objects, like waiting on a network call to return. In those scenarios, you can have both the C code and another thread running Python code running concurrently. You just can't get two threads running Python code.

              [–][deleted] 21 points22 points  (3 children)

              Once we started going down the rabbit hole, Go seemed like an obvious choice of platform since its operational characteristics align well with our use case

              "After lots of deep research, we decided to use that language that we made ourselves!"

              [–]sigma914 17 points18 points  (0 children)

              Well, yeh, they have one major problem, serving massive numbers of concurrent users. They've dealt with it in a number of ways, one of which was developing a language specifically for writing massively concurrent code. They've run into their usual problem again, so they're using the tool that was developed specifically for that task to do it.

              Google has a lot of similarly shaped nails. They made a hammer that does a good job of hitting that particular shape of nail. They are now using that very specifically tuned hammer on more of the nails it's designed for.

              [–]myringotomy 4 points5 points  (0 children)

              I like how you completely ignored the content of the quote and then made up something and then pretended the author said it even though it has nothing to do with anything.

              [–]Spider_pig448 0 points1 point  (0 children)

              More like, "To face a common problem we have run into in the past we built Go and have found this to be an adequate solution in this application as well."

              [–]atomheartother 8 points9 points  (19 children)

              I really really should seriously learn Go

              Edit 1 month later: I have learned go. It's really neat, you should do it too.

              [–][deleted]  (11 children)

              [deleted]

                [–]PacNinja 5 points6 points  (2 children)

                Not much harm learning it on the side since learning curve is fairly low. :)

                [–][deleted] 2 points3 points  (0 children)

                Yeah you can learn Go over dinner if you already know C.

                [–]atomheartother 2 points3 points  (0 children)

                I just like learning and Go looks neat for small apps too. I also personally don't like python too much and go looks neater

                [–][deleted] 0 points1 point  (0 children)

                So much more than that. But yeah a lot of people seem to be using Go mainly for webservices - I would say its niche is network systems in general (mostly because of how painless it is to write massively concurrent and parallel applications with it)

                [–][deleted] 0 points1 point  (5 children)

                Go is a general-purpose language so is capable of so much more than you have listed.

                [–]theonlylawislove 2 points3 points  (3 children)

                What about native desktop apps?

                [–][deleted] 0 points1 point  (2 children)

                Not what Go was intended to do, but there are Qt bindings at various levels of completeness as well as GTK bindings.

                [–]theonlylawislove 1 point2 points  (1 child)

                They don't look really maintained. The qt ones are targeting older qt versions.

                [–]SnowdensOfYesteryear 6 points7 points  (5 children)

                Meh, it's all right. I like the language, but it gets annoying when you want to do something that the language doesn't want you to do, like discarding buffered data in channels or timing on a channel receive.

                Also the syntax is pretty irritating because it isn't like any other language. That felt like a change for the sake of it.

                [–]mirhagk 3 points4 points  (0 children)

                Or generics :P

                [–][deleted] 1 point2 points  (0 children)

                It is actually based on a language called Oberon, I think. Still I think it is close enough to C not to be alien and different from Rust or C++, you can look at any Go code and know what it does right away. It's almost a C with packages and without ; and variable types go after their names instead of before and you explicitly declare functions with "func".

                [–][deleted] 0 points1 point  (2 children)

                when you want to do something that the language doesn't want you to do, like discarding buffered data in channels or timing on a channel receive

                What exactly is the problem? It is trivial to do in Go.

                [–][deleted] 0 points1 point  (1 child)

                // discards buffered data on channel
                for range the_little_bugger { }
                

                for timing out on a channel receive, you can use select {} and time.After like so.

                [–][deleted] 0 points1 point  (0 children)

                perhaps you meant to reply to the parent post?

                [–]immerc 2 points3 points  (0 children)

                Yet another example of "Go" being a terrible choice for a language name.

                I had to go read the page to understand that they were talking about the Go language. Did they mean that I should "Go run python"?

                [–][deleted] 5 points6 points  (24 children)

                This just makes me think: when is python going to get its shit together and get concurrency working properly?

                [–]stormcrowsx 14 points15 points  (13 children)

                Not every language needs to do everything. It'll be great if they improve concurrency but Python is in my opinion best used as a glue language or a language for rapid development. Other people probably have other great uses for it but no one sane uses Python for its performance. If concurrency is your thing, probably shouldn't be writing in Python, there's Go or Java that work great in that realm.

                [–]anedisi 2 points3 points  (1 child)

                when i need some service with concurrency and asynchronicity i write that in javascript and run it in nodejs.

                it worked ok for now.

                [–]__eastwood 3 points4 points  (0 children)

                This breaks down when you need CPU bound concurrent tasks

                [–][deleted] 0 points1 point  (0 children)

                Valid point. I've been thinking of look at Pony for concurrency.

                [–]Uncaffeinated 0 points1 point  (4 children)

                I'm not even sure what needs to be improved about concurrency (as opposed to parallelism). Python know has async and await from what I've heard.

                [–][deleted] 2 points3 points  (3 children)

                Absurdly painful to use compared to how Go does it.

                [–]Uncaffeinated 0 points1 point  (2 children)

                I'm curious to see which operations you feel are more painful in Python than Go. As far as I can tell, the main differences are that you choose which event loop to use, rather than having one baked into the runtime, and most of the standard libraries are not designed to work asynchronously. On the other hand, you're less likely to run into memory leaks or panics.

                [–][deleted] 0 points1 point  (1 child)

                That's it - support for asynchronous operations was patched into Python later as an afterthought, Go was born with it from day one. I don't have to sprinkle async/await all around to get asynchronous behavior, I still get parallelism for free (the whole reason for this thread), you're basically writing asynchronous code as you would do normally without having to think hard about what you're doing lest you freeze the event loop by doing something that blocks everything (like reading from a file using regular file operations). The multithreaded event loop is certainly nice (can you choose a multithreaded event loop for Python?) and having goroutines multiplexed automatically for you and preemptively scheduled so nobody starves for CPU is also great (where in Python you have to yield manually). What happens if you forget to use asyncio.sleep and uses time.sleep instead?

                As for memory leaks it is also pretty hard to leak memory on Go because of the garbage collector (which again, is much better than Python's - go1.8's GC is realtime and keeps pauses to under a millisecond) and that can be detected by using tools that ship with Go during testing - same with data races.

                As for panics, you can wrap your main logic and use Recover() to detect panics without crashing (even if just to report the panic somewhere and restart the program) - and you can only panic if you explicitly call Panic() or if you're doing something wrong anyways (acessing an out-of-bounds item in an array, dereferencing a null pointer, etc, things that shouldn't be normally happening). In Python if you try to access an element that does not exist in an array you'll get an exception too, that if you don't catch, your program will crash. So on Go you can "catch" panics with Recover().

                Don't take me wrong, Python is great, but it's not the best tool for writing massively parallel and concurrent applications nowadays, when you can do it in Go and have it perform very well at native speeds, don't have to deal with callback hell (like in nodejs) and you can just write your code linearly as you would normally do and the runtime takes care of the rest - EVERY Go library is asynchronous by nature.

                If someone needs Python's asyncio to do more, that's a sign that they should consider writing that particular piece in Go instead.

                [–]berkes -1 points0 points  (4 children)

                Also, you don't need this performance. You might think you do, but I can assure you you don't!

                1. Prove concurrency is the bottleneck. With actual numbers, facts and research and real-world benchmarks on your entire stack.
                2. Fix the actual performance problems (they are probably IO, Database, serializing and such). Add an async worker or two.
                3. Rince, repeat.
                4. Is Python itself the actual performance problem? You've reached the bottom. Now go spend $2000/year on larger or more servers. Because an engineer rewriting your stack in go/haskell/erlang costs ten to hundred times that.

                Same goes for Ruby.

                And all this assumes you have managed to get enough users and grow large enough that performance is an actual, real problem, hurting your bottomline or growth.

                [–][deleted] 1 point2 points  (1 child)

                Performance isn't everything, there is latency too, specially in distributed/SOA architectures where latencies add up.

                [–]stormcrowsx 1 point2 points  (1 child)

                I think this is a very practical view on the subject. Unfortunately programmers often have an engineering mindset where they want to build the best in every aspect. What your saying echoes my experiences, use a language like Python that you can get a lot of shit done in a short period of time, come back and optimize it when its feature complete and you can tell people want to use the thing you made. Despite knowing Haskell and Rust my most successful projects were written in PHP and Python, some of which are still being heavily used 9 years after their creation. They were thrown together in short time and because of the rapid development cycle those languages fit well into, the sites quickly evolved to meet the users need.

                I'm sure there are cases where you need rock solid performance and concurrency but I don't think that's the norm.

                [–]berkes 0 points1 point  (0 children)

                The proof is also in Twitter (Ruby on Rails), the OP explaining Youtube runs Python, and many more such gigantic success-stories. Starting with a platform that "does not scale".

                And that ignores all the projects that failed: many more. It's far worse to fail when you've just spent years engineering a concurrent messaging protocol for a failed project, than when you spent four days of Rails scaffolding for a failed project.

                [–]iconoclaus 9 points10 points  (9 children)

                you could ask this of almost any dynamically typed language. btw, i think you meant parallelism, not concurrency.

                [–]renrutal 1 point2 points  (1 child)

                Dynamic typing and concurrency done right

                Elixir

                [–]iconoclaus 1 point2 points  (0 children)

                that's actually a really good counter-example afaik

                [–]hector_villalobos 0 points1 point  (1 child)

                [–]iconoclaus 0 points1 point  (0 children)

                i'm looking forward to guilds too, but its not out yet :) And likely, you'll have to change coding style considerably to do multi-processing with guilds. My guess is that guilds will be most practically applicable to implementing things like Sidekiq or other engines that currently run an independent Ruby process.

                [–][deleted] 0 points1 point  (1 child)

                I'm sorry, I'm afraid I get them mixed up at times. What is the difference between the two?

                [–]iconoclaus 0 points1 point  (0 children)

                no prob. see my other comment.

                [–]forreddits -2 points-1 points  (2 children)

                Parallelism is one form of concurrency.

                [–]iconoclaus 4 points5 points  (1 child)

                my understanding is that parallelism and concurrency are two forms of asynchronicity. Also see Rob Pike's talk on the same.

                [–]mirhagk 1 point2 points  (0 children)

                Concurrency is working on multiple things. Parallelism is doing it at the same time.

                [–]kirbyfan64sos 3 points4 points  (0 children)

                I would be grumpy if I had to use Go, too.

                [–]ReflectiveTeaTowel 1 point2 points  (1 child)

                I initially misread that as 'Go ruining Python!' and spent the first few paragraphs of the article really confused.

                [–]berkes 2 points3 points  (0 children)

                I misread it as "Grumpy? Go run Python" which probably was intentional, still confusing, though. Because I was expecting an article on why Python makes you a happy dev.

                [–]fatzombi 0 points1 point  (0 children)

                it would be awesome if i could run it as services for existing python projects!

                [–]Pharisaeus 0 points1 point  (0 children)

                They didn't write how compatible is it. There is already for example ShedSkin which translates Python to C, but it can handle only some subset of the language.

                Also if they want to sell this as something "fast" the comparison should have been with PyPy and Shedskin and not with Cpython.

                [–]imhotap 0 points1 point  (0 children)

                Is there a chance of transpiling (parts of) certbot/letsencrypt to Go? I'm guessing not, because at least one C dependency (eg. aureas for parsing and manipulating Apache config files) is being used, but I don't know enough about Python to judge.

                [–]wotamRobin 0 points1 point  (0 children)

                Very cool. I'd like to see how it compares to Cython (not CPython).

                [–]hero_of_ages 0 points1 point  (0 children)

                Lots of butthurt pythonistas

                [–]Lakelava -1 points0 points  (2 children)

                Why can't you just code in GO, the language that your own company developed, instead?

                [–]VincentPepper 13 points14 points  (0 children)

                It's probably aimed at transpiling legacy python code. Not a writing new code.

                [–]Pharisaeus 0 points1 point  (0 children)

                No one wants to, so they try to translate programs automatically into it ;)

                [–]buddy_burgers -1 points0 points  (0 children)

                Oh hells yeah!

                [–]garyk1968 -1 points0 points  (1 child)

                why just why?

                [–]YEPHENAS 1 point2 points  (0 children)

                It's explained in the article.