4 ms·
As I said, others complain about break & return. Defanged to you is not defanged to others no matter how often/consistently you say so. The statement & many o
by cb321 4y ago
As I said, others complain about break & return. Defanged to you is not defanged to others no matter how often/consistently you say so. The statement & many of its claimed problems persist. Call the remaining problems claws not fangs. Safety/clarity is also hard to quantify. Persistence+present rarity shows abolishing was not needed for use to fade.
Portability of longjmp can mean over (at least) CPUs, libc's, OSes, assembler backends (gas vs Intel syntax). Semantic hair splitting about what difference achieves "practical", what support (by who,what,when) achieves "actually" or other squishy traits adds no insight. Sorry you're frustrated, but I don't think there's anything more to say on goto we haven't both said >=1 times. We'll just have to agree to disagree on goto.
--
On a far more practical note (that makes goto analogy even more dubious and even less worth debating), one problem with this <=1965 approach that is charming you lately is uniformity of job sizes (in time). Since the block waits for the last of N tasks to finish, utilization is capped by the slowest finisher.
This "must wait for last of N" is at least part of why this has been more popular in parallelism settings like OpenMP than in network concurrency settings. As one simple, heuristic model, the distribution of the sample max is the N-th power of the distribution function. [1] So, e.g. 1/2=F^N => (1/2)^(1/N)=F => median of max(N) is the N-th root of the median. E.g., 0.5^0.01=0.993 for N=100. The 99.3rd percentile of WAN latencies can be very long indeed (and often even minimal job chunks require facing that).
Often you won't know ahead of time who the slowpokes will be to "launch those in the background". You might test "in-data-center" and have utilization crash "cross region". It might only be "intended for in-data-center" and be misused or some in-data-center host may break. In a parallel setting, maybe some data is in L3, some in RAM, others on NVMe, others still on spinning rust or across a network + any of that other uncertainty. Disparity almost always grows with N. There are mitigations (e.g. elastic parallelism to at least keep things busy if possible, multiple pools & task migration, etc.), but duration disparity can be a real problem - things that work in tests can "perf fail" elsewhere.
The point here is that complexities & sensitivities to deployments/context exist in this replacement idea that simply did not for "goto". Technical debt acquired by "total removal" could cost more than you save by simplicity in a few ways. These things are not easy to quantify. Maybe this is all obvious. But maybe not. I did not see such mentioned in any of the 3 discussions so far (in search for text near "last" "wait" "long" "slow" "idle" or "util", anyway) in over 300 comments so far.
[1] https://en.wikipedia.org/wiki/Extreme_value_theory https://en.wikipedia.org/wiki/Extreme_value_theory
- tialaramex 4y ago> one problem with this <=1965 approach that is charming you lately is uniformity of job sizes Er, no. I can imagine Dijkstra may have faced similarly confused people, who just couldn't understand how (for example) a loop feature should replace their use of a go-to for conditionals. Dijkstra does not propose a single new language feature to replace go-to one-for-one, and indeed makes clear in his letter that although this has been proven technically possible it's obviously the Wrong Thing™, likewise the replacement for go statements isn't a single "must wait for last of N" feature. Just as modern programs typically have loop constructs, and conditional constructs, and procedure constructs even though a go-to statement could have expressed all these and more, the idea is that you could have several different concurrency mechanisms, each better suited for its purpose than the "go statement" and similar features today. I think we'd want semi-short-cutting concurrency for example. Suppose there are computations F1, F2, F3, F4. In serial programs we can imagine writing f1() && f2() && f3() && f4() to have each computation happen only if the previous computation was unsatisfactory in some way because we have short-cutting && operator. But as a concurrency primitive you might like to have a way to perform F1, F2, F3 and F4 so that perhaps all four might happen however once you have a satisfactory answer from any of them the computation overall stops. Unlike the short cutting && operator this would not promise that F4 doesn't run if the others succeed but it would promise not to expend further computation after the answer is discovered. Now, of course you can build this from the more powerful "go statement" primitive, but that's not the point here, you could build the short-cutting && operator from the go-to primitive too. The point is that having a sufficient arsenal of such structures provides clearer concurrent programming which empowers us to write more complex concurrent programs that are correct.
- cb321 4y ago>> one problem {i.e. "insufficiency of arsenal" in your lingo} > Erm, no [..needless snark, insinuates I'm confused.. proceeds to largely restate Smith's article and himself, though a little better this time; Good job! but does not solve the problem if a user wants even "most" of the N answers..] I suppose I could have instead said "exist in this one replacement idea[..]could cost more than you save either in other constructs or in mitigations" or something similarly guarded/defensive. Seems you probably would have picked yet another strawman or willfully obtuse reading to attack rather than argue in good faith. If you do not have positive "arsenal addition" suggestions to solve the essence of the problem I mentioned -- which I am pretty sure many care about -- whatever gripe you might have with how I describe it then I don't think we have anything more to say to each other here.