[CentralOH] Additional Go Language Influences
Eric Floehr
eric at intellovations.com
Tue Feb 24 21:05:36 CET 2015
> Will Python develop a lightweight concurrency model?
>
>
> Python has some external projects which have introduced the idea of "green
> threads", such as greenlet and gevent. However, I think Go's greatest
> strength is that the concurrency is baked in at a very fundamental level in
> the language and runtime. Gevent for instance does some pretty scary
> monkeypatching of various low-level functions in places like the socket and
> os modules to achieve concurrency.
>
I agree that baking in concurrency at a fundamental level is Go's greatest
strength. I would argue however, that Python has baked in almost to the
same level concurrency, and that you rarely if ever need to use third-party
green thread implementations any more.
The main concepts are that generators are semi-coroutines, coroutines allow
for concurrency, and cocurrency is not multi-threading.
Both Python and Go by default implement concurrency on a single
thread/virtual processor. Go's advantages are that it is slightly easier to
grok goroutines because of less syntactic sugar needed (like the event loop
is implicit not explicit), and that you can more easily introduce
additional (virtual) processors (via runtime.GOMAXPROCS) whereas in Python
it's a little more difficult to introduce multi-threaded concurrency. Also,
Go's asynchronous I/O is built-in to the standard I/O libraries in Go
(that's changing in Python though).
> I think to get the kind of concurrency Go enjoys would require a Python
> 4-like re-breaking of the language syntax, which I think would be a tough
> sell. Maybe it could be done incrementally, I'm not sure.
>
I don't agree with this at all. To get everything that Go has, the way it
has it, maybe. But if you want to write Go, write Go. But to enjoy
concurrency as Go enjoys it (but perhaps implemented differently), it's
already there in Python.
One of the things I like best about Go is that goroutines allow you to
> write code in a very linear, sequential, non-concurrent fashion and add
> asynchronicity later. If you look at my first example from the talk, the
> concurrent URL fetcher:
>
> https://github.com/joeshaw/talks/blob/master/cohpy/fetch.go
>
>
notice that the fetch() function does not involve concurrency at all.
>
Right, but the reason that works is because Go provides non-blocking HTTP
and File operations by default. In Python 3 we get non-blocking file I/O,
and via third-party libs we can get non-blocking HTTP (aiohttp) and
hopefully that will be added in soon as more people convert to the
non-blocking sockets in Python 3.
So the only advantage with Go is that it isn't hindered by some blocking
legacy code, which is true of any shiny new language.
It is how we use and compose that function later inside main() that makes
> the concurrency work. It's a best practice in Go that APIs you write
> should not expose goroutines or channels but instead act synchronously.
> The consumers of your API should have the freedom to make them asynchronous
> by running them in a goroutine.
>
So how is Go's:
for i := range sites {
site := sites[i]
go func() {
resultCh <- fetch(site)
}()
}
for res := range resultCh {
fmt.Println(res)
}
that different from Python 3's (assuming fetch used non-blocking http and
file i/o, as Go):
def func(site):
result = yield from fetch(site)
print result
funcs = [func(u) for u in sites]
asyncio.get_event_loop().run_until_complete(funcs)
Sure you don't have channels in this example, but we don't really need
them. And Go's event loop is implicit. I don't claim to be an expert in
Python 3's asyncio so there may be even better ways to do this, but I don't
really see any huge Go advantage or difference here.
While I think the asyncio stuff in Python is really great and a big
> improvement over things like gevent (or even Twisted), like C#'s
> async/await syntax it "infects" your code by making it necessary to yield
> within (or in C#, mark async) any code that needs to run asynchronously.
> It can become a fairly large burden to convert code from being synchronous
> to asynchronous because it often affects large portions of your call stack.
>
Coroutines have been first-class Python since 2.5, so sure, it's not baked
in from the beginning. So a Go programmer is more likely to use async and
goroutines from the beginning.
But I don't understand how making non-concurrent code in Go concurrent any
less "infectious" than making non-concurrent code in Python concurrent?
As noted from my example above, it's no more "burdensome" to make
non-concurrent "fetch()" in either Go or Python concurrent.
Anyway, I do enjoy what Go offers, and have been very interested in the
language. It does offer some cleaner syntax and built-in stuff, as well as
bringing less baggage :-) that make it appealing.
Cheers,
Eric
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/centraloh/attachments/20150224/1b1282eb/attachment-0001.html>
More information about the CentralOH
mailing list