func sorttask(inchan chan []string, outchan chan []string) {
list := <- inchan // data received from sending task
sort.Strings(list) // sort
outchan <- list // results returnd to sending task
}
func dosort(in []string) []string {
inchan := make(chan []string)
outchan := make(chan []string)
go sorttask(inchan, outchan)
inchan <- in // data sent to sort task, sort starts
result := <- outchan // wait for data from sort task
return result
}
On Jan 19, 2013 3:13 PM, "John Nagle" <na...@animats.com> wrote:
> The "do not communicate by sharing memory; instead, share memory by
> communicating” line in "Effective Go" is misleading. Erlang has that
> property. Go doesn't.
Erlang doesn't share memory. Go allows you to share memory by communicating. Erlang only lets you share values by communicating. Each has trade offs.
--
You just have a huge increase in memory allocations and gc pauses to worry about.
FYI: tip is auto-switching between {heap,insertion,quick}sort.
No. Access and visibility are not the same thing.
--
On Jan 19, 2013 7:56 AM, "John Nagle" <na...@animats.com> wrote:
>
> On 1/18/2013 10:45 PM, Rob Pike wrote:
> > On Fri, Jan 18, 2013 at 8:13 PM, John Nagle <na...@animats.com> wrote:
> >> The "do not communicate by sharing memory; instead, share memory by
> >> communicating” line in "Effective Go" is misleading. Erlang has that
> >> property. Go doesn't.
> >
> > We don't claim Go has that property. Instead, we assert that the
> > language works best if your programs have that property. It's a motto,
> > not a feature.
>
> This is what "Effective Go" says:
>
> "Concurrent programming in many environments is made difficult by the
> subtleties required to implement correct access to shared variables. Go
> encourages a different approach in which shared values are passed around
> on channels and, in fact, never actively shared by separate threads of
> execution. Only one goroutine has access to the value at any given time.
> Data races cannot occur, by design. To encourage this way of thinking we
> have reduced it to a slogan:
>
> Do not communicate by sharing memory; instead, share memory by
> communicating."
>
> Again, this is what is claimed for Go:
>
> "ONLY ONE GOROUTINE HAS ACCESS TO THE VALUE AT ANY GIVEN TIME. DATA
> RACES CANNOT OCCUR, BY DESIGN."
>
> That statement is false.
>
> The author of Effective Go has a bright future writing advertising
> copy.
You are misreading the plain meaning of the text ("Go encourages a different approach," not "enforces"). Why?
Ian
On 1/18/2013 10:45 PM, Rob Pike wrote:
> On Fri, Jan 18, 2013 at 8:13 PM, John Nagle <na...@animats.com> wrote:
>> The "do not communicate by sharing memory; instead, share memory by
>> communicating” line in "Effective Go" is misleading. Erlang has that
>> property. Go doesn't.
>
> We don't claim Go has that property. Instead, we assert that the
> language works best if your programs have that property. It's a motto,
> not a feature.
This is what "Effective Go" says:
"Concurrent programming in many environments is made difficult by the
subtleties required to implement correct access to shared variables. Go
encourages a different approach in which shared values are passed aroundexecution. Only one goroutine has access to the value at any given time.
on channels and, in fact, never actively shared by separate threads of
Data races cannot occur, by design. To encourage this way of thinking we
have reduced it to a slogan:
communicating."
Do not communicate by sharing memory; instead, share memory by
Again, this is what is claimed for Go:
"ONLY ONE GOROUTINE HAS ACCESS TO THE VALUE AT ANY GIVEN TIME. DATA
RACES CANNOT OCCUR, BY DESIGN."
That statement is false.
But given that perfection has not yet been
shown to be feasible, Go is not bad.
Ian
Those sacrifice control, and can be emulated through voluntary use of other techniques already available in Go. Self-discipline is an excellent substitute for manacles; if a programmer is incapable of exercising self-discipline, then use of other languages may be a far better choice.
Because the later is equivalent to the halting problem?
-j
Go is being promoted as something as easy to use as Javascript,
Perl, or Python. But it's not yet as safe. This is a problem.
On Sat, Jan 19, 2013 at 11:59 AM, Jan Mercl <0xj...@gmail.com> wrote:Because the later is equivalent to the halting problem?
See C++'s const, D's const/immutable, and Rust's immutable references.
But do they solve the whole problem of writing concurrent software?If not, why does Go have to adopt these incomplete solutions?Maybe there are better solutions in the future, why not wait and see?
Unless the systems programming language does away with null pointers in the first place ;) Rust is taking this approach.
--
Now we have soundness, but it's cost us some copying.
Can those copies be optimized out? Yes.
The optimization needed here is like tail recursion.
If the last access to a reference before it goes out of
scope is a send, then it need not be copied. In
the example above, both deep copies can be optimized out.
From the programmer perspective, this optimization is
invisible. As with tail recursion, it's valuable for
programmers to know this is going on, and it should
be guaranteed to the programmer that this happens in the
simple cases.
This covers one of the major use cases in server-side
programming - a program makes multiple requests to
John Nagle
--
John Nagle
--
On 1/21/2013 12:19 PM, Patrick Mylund Nielsen wrote:That's the problem I'm trying to solve. Having solved some tougher
> Go makes it easier to play it safe, but it does not guarantee it. I don't
> know that you could do what you're asking and keep the language familiar to
> people who know traditional "imperative" languages.
problems in the past, it doesn't look impossible. Just hard.
We don't have to go to something exotic like a functional language
or single assignment or single ownership pointers to fix this.
Javascript programmers are already used to Java's pseudo-concurrency
model based on callbacks. That works out surprisingly well, even though
the Javascript crowd tends to use global variables to communicate with
callbacks when they should be using closures. It might be helpful to
have a way to to turn the "send on channel, wait for reply on another
channel" idiom into something that looks like a Javascript callback.
That may be unnecessary, but it's an option if the idiom is too
complex for most users.
Screwups on language safety in a new design are unacceptable. We
already have a collection of bad languages, and the CERT security
advisories that come from them. When you really blow it, it
looks like this:
http://bits.blogs.nytimes.com/2013/01/14/department-of-homeland-security-disable-java-unless-it-is-absolutely-necessary/
“Unless it is absolutely necessary to run Java in Web browsers, disable
it (Java). This will help mitigate other Java vulnerabilities that may
be discovered in the future.” - Department of Homeland Security
> In any case, you're right that the adage in effective Go might give people
> the wrong impression, but this discussion is no longer constructive.
> There's nothing that can/will be done in Go 1 to change the semantics.
“Too often we enjoy the comfort of opinion without the discomfort of
thought.”
John Nagle
--
Javascript programmers are already used to Java's pseudo-concurrency
model based on callbacks. That works out surprisingly well, even though
the Javascript crowd tends to use global variables to communicate with
callbacks when they should be using closures. It might be helpful to
have a way to to turn the "send on channel, wait for reply on another
channel" idiom into something that looks like a Javascript callback.
That may be unnecessary, but it's an option if the idiom is too
complex for most users.
It might be helpful to
have a way to to turn the "send on channel, wait for reply on another
channel" idiom into something that looks like a Javascript callback.
After about twenty programming languages, and watching the mistakes
go by, I'm disappointed with Go. Go is touted as having a safe
solution to efficient concurrency. It doesn't. We need such
a language. We have more concurrent hardware out there now than
concurrent software that can use it. But it's very easy to screw
up concurrent code, and it's very difficult to debug.
We don't have to go to something exotic like a functional language
or single assignment or single ownership pointers to fix this.
John Nagle
--
If this required a deep copy, it
a) wouldn't work, because the layout algorithm would be unable
to change the nodes in place.
b) would be much less efficient, even if we did the copy
in each direction, because of the copying overhead. Each copy would need
two passes through the data and len(g.Nodes) allocations.
The point I'm trying to make is that *thinking* in terms of ownership
of data is a useful way to make it easier to reason about concurrent
programs.
We can look at the code above and verify by eye that it's race
free, assuming the different graphs don't share data,
a property that we can also make easy to verify.
I've found this approach scales quite well, and one reason may
be that it's relatively rare for packages to export a channel-based
API. Packages often use channels internally, but they export
functions or methods that hide that fact.
When a package *does* export a channel-based interface
(almost exclusively a package will send to its client,
not the other way around), the object passed over the channel either
a) has no references (and is thus inherently safe)
or b) has methods which are all safe to use concurrently
or c) is genuinely transferring ownership - the sender
will never refer to the value again.
When each layer of the system conforms to the above
conventions, it's not hard to verify the correctness
of the whole system by looking at each component
individually. Complexity due to concurrency becomes additive
rather than multiplicative.
On 1/21/2013 11:16 AM, minux wrote:...
> On Tue, Jan 22, 2013 at 2:45 AM, John Nagle <na...@animats.com> wrote:
>
>> Now we have soundness, but it's cost us some copying.
>> Can those copies be optimized out? Yes.
>>
>> The optimization needed here is like tail recursion
> If we can't make the guarantee to make this kind of optimization ...
> No. IMO, not guaranteed optimization == no optimization at all or
> even worse.
>
> than we make no enforcement thus no thus guarantee at all.The Scheme specification does mandate tail recursion. See
http://people.csail.mit.edu/jaffer/r5rs_5.html#SEC23