One of Go's big selling points is the avoidance of the "red-blue problem" (https://journal.stuffwithstuff.com/2015/02/01/what-color-is-...). The standard Go implementation does that by using lightweight
"goroutines" that automatically suspend themselves whenever they do some operation that might block - there's no need to use an OS-level thread for each thread of control.
I wonder how the authors plan to accomplish a similar thing while remaining fully FFI-compatible.
> Sure, but more data will be attached to it. Also, in his proposal, he said that IP addresses will not be logged. I seriously doubt that.
I think it's worth quoting what Russ said in the article, which sounds very reasonable to me:
> The server would necessarily observe the source IP address in the TCP session uploading the report, but the server would not record that address with the data, a fact that can be confirmed by inspecting the reporting server source code (the server would be open source like the rest of Go) or by reference to a stated privacy policy like the one for the Go module mirror, depending on whether you lean more toward trusting software engineers or lawyers. A company could also run their own HTTP proxy to shield individual system’s IP addresses and arrange for employee systems to set GOTELEMETRY to the address of that proxy. It may also make sense to allow Go module proxies to proxy uploads, so that the existing GOPROXY setting also works for redirecting the upload and shielding the system’s IP address.
> This means that, except for the fact that I don't work in Go, most of my private conversation with a machine could be backdoored.
I don't get this. Given the design that the article is describing, how could most of your private conversation with a machine be backdoored? Specifically given that the Go tool is open source and used by millions already. Are you worried about sneaky code hidden inside that source code? If so, you should be worried already, because there's no reason that they couldn't already be doing that if they were so inclined.
> First, making network requests when downloading packages is necessary for the tool to function and unavoidable.
It's technically not unavoidable. The Go authors could have made use of the proxy opt-in rather than opt-out, making the tool less usable as a result. A similar argument applies here, I think.
> Second, the Go telemetry would apparently create a unique, persistent user ID
Where did you see this? I scanned through the "Telemetry Design" article reasonably carefully and couldn't find any mention of this concept, and the type definition for the posted JSON (the `Report` type) doesn't seem to include any such user ID.
In the end, ISTM that you're not complaining about something that actually affects your privacy in any way, but just the _idea_ of telemetry. Is that really something worth taking such a hardline stance on?
So you see this as just the same, from a privacy perspective, as the way that the Go tool already dials out to the Go proxy by default? That is, if you're OK with that (I'd assume not, but it is at least existing functionality), you'd see the telemetry proposal as similar?
In other words, I think you object to the Go tool already, so this is really no different?
That ship has already sailed. The Go tool already by default makes network requests to the Go proxy, which potentially allows everything that you're talking about there. What's significantly different about this telemetry proposal?
I'm not sure that hiding the implementation is worth it here. Why not just make it public that it's actually map[T]struct{} underneath - then anyone can range on it and implement allocation optimisations, etc? I added some other methods too for the crack https://go2goplay.golang.org/p/EI1hYaSohnc
I think it's interesting to observe that using the Result type is really not that much different from using a multiple return value - it's actually worse in some ways because you end up using "Unwrap" which can panic.
OK, replying to myself for future reference. I found the answer here: https://youtu.be/0GeJdTTzaDo (incidentally, that series of videos seems to have solutions for most of these problems).
The answer is that the left and right side of the notch holds local equivalents to the global "given X, prove Y" connectors. You can use the left side of the notch as an input, and you can connect that up through the global blocks to prove the hypothesis.
That was non-obvious! Also, the technique of connecting the output first and making connections to nothing to see what the implied proposition is was very useful - I should have thought of that.
This was a fun puzzle, but I came to a roadblock here too.
I have to confess I'm confused by what I believe might be the "local hypothesis block" mentioned above. The confusion is somewhat greater because the blocks don't seem to have any attached name or description, so it's not clear what they're meant to be doing.
Up until task 5 in session 2, all the solutions are pretty trivial. But I can't work out what sort of wiring that block implies (for the record, the task is "given (A->B, B->C), prove (A->C)").
It's really not clear to me what the "notch" at the top of that block implies, or how it might be used.
I think there should be at least one "hand-holding" solution for the first use of each block type. Even the papers linked to don't describe the intended semantics of each block.
You can specify that a given dependency be replaced by another one. That only applies at the top level though, not when the go.mod file with the replace clause is used by another module.
Don't keep type safety then. Think of Go as half-way between Python and Haskell in that respect. Types are great when they're useful, but they're not required.
I tend to check out one branch, run godeps -u, then check out the other one and run godeps -N -u. Then you've got the newest deps from both branches. I still wouldn't resolve the conflict manually.
> I'd rather have a test that correctly reasonably verifies that a package is correct (or at least "passes the race detector consistently") and reaches into some of the private details than fail to test a package. Too many bugs I've found that way.
I agree with this, with the caveat that if you can test a package with regard to its public API only, it is desirable to do so because it gives much greater peace of mind when doing significant refactoring.
The difficulty comes in larger software where the package you're testing uses other packages as part of its implementation which also have their own time-based logic. Do we export all those synchronisation points so that importers can use them to help their tests too? If we do, then suddenly our API surface is significantly larger and more fragile - what would have been an internal fix can become a breaking change for many importers.
> Mocking out the time functions means you don't get any race conditions.
This is a common misapprehension. Actually, even if you fully mock out time, you can still get race conditions, because goroutines can remain active regardless of the state of the clock, and there's no general way to wait until all goroutines are quiescent waiting on the clock. This is not just a theoretical concern - this kind of problem is not uncommon in practice.
I think clock-mocking can be very useful for testing hard-to-reach places in leaf packages. But at a higher level, I think it can end up producing extremely fragile tests that depend intimately on implementation details of packages that the tests should not be concerned about at all. In these cases, I've come to prefer configuring short time intervals and polling for desired state as being the lesser of two evils.
The godeps file is just a dependency-per-line, tab-separated values, deliberately so it's easily amenable to shell script processing.
Aside: the conflicts mentioned in the article should never be a real problem because you can always resolve the conflict by just recreating the dependences.tsv file (you should never be editing it manually anyway).
Exceptions don't always give you useful stack traces in a concurrent situation, because the current stack may only reflect a goroutine that's processing data on behalf of another. The real execution context may involve many more.
I wonder how the authors plan to accomplish a similar thing while remaining fully FFI-compatible.