HNHacker News
TopNewBestAskShowJobs

Merovius

729 karma · joined June 14, 2015

submissionscomments
Merovius··on Common Gotchas in Go
No, not really, it's a natural and unintended consequence of how the spec scopes variables in loops/switches/conditionals:

https://golang.org/ref/spec#Blocks

The problem you are trying to solve is, that with a statement like

    for i := 0; i < n; i++ {
        doAThing(i)
    }
you want `i` to be valid inside the loop body, in the for-clauses but not outside the for-statement. Go solves this by saying that an if/for/switch statement has an implicit block surrounding them and that block is what scopes the loop variables. AFAIK no one considered, that this would have this consequence in relation to closures.

Performance wouldn't really matter, because compilers tend to be pretty good at optimizing these kinds of things. They already reorder when they check for the condition and how they jump non-intuitively and the naive instruction sequence would involve freeing some stack-space at the end of the loop, reallocating it in the next iteration and then writing the new value to it. Figuring out that you can save the actual stack-pointer operations isn't that hard.

Merovius··on Common Gotchas in Go
> Hypothetically, if the language defined for i, x := range xs to have x repeatedly be a new reference to each of xs members, it seems like we'd avoid 2 gotchyas

I'm not convinced. I believe what you'd end up with is that someone will write a "Common Gotchas in Go" article about how, if you think you are operating on a copy in the loop, you are actually operating on a reference.

Really, it seems very non-obvious to me, why one would be a less surprising behavior than the other.

(The fact that the loop variables are not scoped to the loop body - i.e. closures will share the references - is another issue and that I would pretty unambiguously call a gotcha that should be fixed…)

Merovius··on Diminishing returns of static typing
> they are far too trivial.

You'd have thunk I didn't have to make them than. But I did, judging from literally every argument I had about this.

Merovius··on Diminishing returns of static typing
Sorry, you are right, of course. I fell victim to one of the internet's classic blunders: Skimming a long comment thread and not carefully read what I reply to in the end :)
Merovius··on Diminishing returns of static typing
> It is impractical to expect go’s designers to have foreseen the best trade off for every codebase.

Which is not the argument made by anyone. Indeed, I explicitly acknowledge that there is a certain fraction of use-cases not covered by the builtins. So there isn't really any disagreement about this.

The question is how large this fraction is, how much it would benefit and how inconvenient/costly the existing workarounds are. Like all engineering questions, these are impossible to talk about when dealing in absolutes. And once you actually talk about these questions quantitatively, I achieved the goal I had with the post - to change the debate into a quantitative one explicitly acknowledging the tradeoffs involved.

> Architecture astronauting can be prevented with best practices and code review, not with language limitations.

I work at a company which has probably one of the highest standards in regards to code review in the industry. As such, I disagree with you that it is effective in addressing this.

> It’s a fools errand to try, code generation allows you to get all the complexity and more of generics.

If that's the case, where do the complaints come from about the lack of generics? It seems that Go really has generics then, in your opinion?

Of course, that's a strawman and a misrepresentation of your argument. But what makes this a strawman, the difference between the existing workarounds and actual generics, is just as effective an argument for your side as it is one for my side. Because codegen is made so inconvenient, people bias heavily towards using the builtins, away from custom data structures, if they can at all get away with it. Thus greatly reducing the overall complexity of the codebase.

So it would seem to me, that this argument is logically flawed. Either codegen is a poor replacement, thus leading to people using less generic code, thus there is an effective reduction in complexity. Or codegen has the same effect on complexity, which would mean it is used just as much, meaning it can't be that bad a workaround.

Merovius··on Diminishing returns of static typing
The fact that maps/slices/channels already exist generically is what puts Go into the sweet spot. You have generic containers for the vast majority of use-cases, so the value-added consideration of being able to cover more use-cases with generic containers becomes a lot smaller.

In a hypothetical world where the designers never added the specific containers they did, you'd get a whole lot more value out of generics for containers. But it turns out, the designers used what seems on the surface like a kludge to get most of the benefits, while saving most of the cost. It's a perfect embodiment of the kinds of tradeoffs I'm talking about.

Merovius··on Diminishing returns of static typing
> I think the OP is fundamentally right about the sweet spot being pretty far from either extreme, I just disagree slightly about where exactly :)

And I think an important take-away should be, that this perception is entirely subjective and colored by both of our experiences, preferences and the kinds of problems we work on :)

Merovius··on Diminishing returns of static typing
The article makes two main points: a) static typing has a cost and b) thus, any benefit it brings should be examined against that cost.

I am sorry, but I don't really see how you stating more benefits of static typing really counters either of them.

I recommend reading the article again. But this time, try not to read it as defending a specific language (I only mentioned my blub language so that it's a more specific and extensive reference in the cases where I use it - if you are not using my blub language, you should really just ignore everything I write about it specifically) and more as trying to talk on a meta-level about how we discuss these things. Because your comment is an excellent example of how not to do it and the kind of argument that prompted me to this writeup in the first place.

Merovius··on Diminishing returns of static typing
> For example I can prove my my string reverse works in Idris (https://www.stackbuilders.com/news/reverse-reverse-theorem-p...).

This article basically demonstrates GP point, though. It proves that `reverse` is self-inverse, but there are lots and lots of functions that are self-inverse (for example, `x -> x` is self-inverse. As would be the function that swaps any odd-index element with the one following it).

The claim was a difficulty of how to encode the actual correctness into your type-system. That this article doesn't actually encode correctness of reverse, seems like pretty good for that difficulty.

Merovius··on Diminishing returns of static typing
> The author of the article implicitly equates "statically verified code" with "bug-free code".

Not at all. First, the statements as put here are discrete (boolean even) while I present both "statically verified code" and "bug-freedom" as living on a continuum. Secondly, I don't equate them. If anything, I assume a monotonic, positive relationship between them (strictly speaking not even that. I make pretty clear that the curves could also have whatever shape. But I yield that I am very suggestive in this because I do strongly believe it to be the case). In fact, one of the main points of the argument is that the two are not equal - otherwise, the blue curves I drew would all be straight lines from (0,0) to (1,1). And lastly, none of this is done implicitly. I mention all of this pretty explicitly :)

Merovius··on Diminishing returns of static typing
It does (though admittedly not very explicitly), it just rolls it into the "benefit" (i.e. not shipping broken code is a benefit) and the "weight given to stability". If a bug discovered in prod (or even qa/canary) has a significantly higher cost than a bug discovered early, that will influence the weight you are putting on stability. In that way, this factor is subsumed in one of the other graphs.

As you might've noticed, I have been intentionally light on the details and only talked pretty abstractly about the specific scales and factors involved.

Merovius··on Diminishing returns of static typing
> Well, the easy answer is that dependently-typed languages like Agda and Idris aren't very mature yet.

It's also self-evidently wrong. Agda was first released in 1999, ten years before Go. If you use a wallclock interpretation of "maturity", Agda is twice as old as Go and Idris is roughly as old as Go. Both are used significantly less (by several orders of magnitude), though. Despite them having a far stronger type-system.

If you, on the other hand, you are using a "developers' time" interpretation of maturity, on the other hand, you are making a circular argument, i.e. "Agda is seeing less use, because it has been used less", as resources invested in a language ecosystem tend to be strongly correlated with it's usage.

Merovius··on VLC maintainer has refused “several tens of millions of Euro”
> I used that to segue into quite a rant about how I lamented the lack of complexity in software.

A software that does the right thing for everyone without any settings is several orders of magnitude more complex than a software that just lazily requires its users to configure it.

Merovius··on Why Go is my favorite programming language
> Here, both x and y are conceptually nil, but y cannot be compared to nil.

I disagree with the "conceptual nilness" of y. x is a perfectly fine and usable implementation of io.Closer. It doesn't even panic. Having a nil-check (i.e. "does this interfaces contain a value?") return true seems dishonest to me.

I agree, that it was a bad choice to call both the zero-value of pointers and the zero-value of interfaces "nil". But in general, the possibility of nil-pointers being valid values and implementers of interfaces is useful. For example if you have a linked list or graph-structure.

I also asked about it on reddit and got this answer: https://www.reddit.com/r/golang/comments/6sktsr/typed_nils_i...

Merovius··on Why Go is my favorite programming language
Yes, Type safe. You can not interpret something as a different kind of type via the use of interface{}. Contrast that with void-pointers, which make that so easy as to be a common bug-source.

It's not statically type-checked, yes. That's fine too, in my opinion, but also irrelevant for a comparison with void-pointers (because they also don't provide that).

In summary, interface{} is strictly better than void-pointers. Which was exactly my point. Equating the two is intellectually dishonest.

Merovius··on Why Go is my favorite programming language
> I said "it's unsafe", not "it's not safer than void".

I'm sorry, but then you're simply in the wrong thread. You where replying to a interface{} vs. void comment, so that's what you should be talking about.

Merovius··on Why Go is my favorite programming language
> Golang can have less keywords, because it has less features.

So, you are saying… because it's less complex?

Merovius··on Why Go is my favorite programming language
I know this is repeated often, but only because it apparently still has to: interface{} is very different from void*. It carries type-information with it. That makes it safe.
Merovius··on How to confirm a Google user’s specific email address
Given that I regularly see my Facebook account name and photo on third party websites, without giving them any permission to see those, I find it hard to believe that Facebook cares about this…
Merovius··on Google Fires Employee Behind Controversial Diversity Memo
Your interpretation of that statement makes no sense. With that interpretation: a) the bar isn't lowered in any sense of the word, as that would imply less qualified people getting in, b) you'd claim that for unexplained reasons, Google can give more accurate evaluations for diversity candidates, c) and/or that they are rejecting candidates they know unequivocally to be qualified and d) even if all of this was the case, there wouldn't be anything discriminatory about it. At least where I'm from, it is literally a legal requirement, that if multiple candidates compete for the same position, diversity candidates are given preference.

Even in its most generous reading (yours), this sentence makes zero sense.

Merovius··on Using Hilbert Curves to 100% Zelda
Yes, but we wouldn't actually walking the whole snake, just as we are not walking the whole Hilbert curve. We are walking the point cloud in the order dictated by either, and those will, in general, differ.
Merovius··on Using Hilbert Curves to 100% Zelda
I tried describing here https://www.reddit.com/r/programming/comments/6oxra8/using_h... why I think that this is theoretically a TSP problem, I don't consider that necessarily the best way to treat it. tl;dr is, that at least to me, at the time, for this problem, the speedup of an optimal solution wouldn't have outweighed the additional thinking time to get to that optimal solution (and, most importantly, to actually make it useful; after all, I wasn't actually drawing a path, I was outputting a list of names).

You can even see that in the argument I added to the post; while a zig-zag line might've been, in theory, a stupider, easier way to solve the problem, in practice it would've meant spending some time thinking about the right discretization. With a Hilbert-curve, I could just choose some n that is definitely large enough and be done with it and the additional cost of the more complicated curve doesn't really factor in, as I could just copy-paste it anyway.

But yes. The theoretical problem is a TSP and with the right set of tools, I could've added some efficiency to the search by viewing it as such.

Merovius··on Using Hilbert Curves to 100% Zelda
Yes. Crash-course complexity theory:

This is easy to understand with integer factorization: It is very hard to factor large integers. Yet, if I where to give you two numbers, it is very easy to verify that their product is the integer you where looking at. So factorization is easy to verify, but hard to do (side-note: This is an intentional illustrative simplification. Integer factorization is not known to actually be "hard" and it is not known whether "hard" is even a thing. See below).

And that's the definition of an NP problem: It has a polynomial time deterministic algorithm to verify a solution.

An NP-complete problem is a problem that is at least as hard as any NP problem. That is, if you have an algorithm for an NP-complete problem, you can take any NP problem, transform it efficiently into that problem, use your algorithm and transform the solution efficiently back. Thus, if you've solved an NP-complete problem efficiently, you can solve all NP problems efficiently. TSP is NP-complete. Whether or not Integer Factorization is NP-complete is unknown.

Lastly, there is the question of whether there are problems that are in NP (that is, have a polynomial algorithm to verify a solution) but not in P (that is, have a polynomial algorithm to find a solution). That's the famous P vs. NP question, which is currently undecided.

Merovius··on Using Hilbert Curves to 100% Zelda
If it isn't, I'm invoking my right to English incorrectly, given that it's not my native language ;)

(yes, I'm being toung-in-cheek by using "English" as a verb here :) )

Merovius··on Using Hilbert Curves to 100% Zelda
This is really interesting, thanks for linking :)
Merovius··on Using Hilbert Curves to 100% Zelda
As this was only about efficiently enumerating the missing locations, not walking them, that's fine. I.e. I had to find the ~5 needles in the haystack of hundreds that I needed to visit. Given that sparseness, it was most efficient to just jump to the nearest warp point and directly go there.

Elevation and the like would be more interesting to figure out what's the most efficient way to collect all Korok Seeds, for example, when the interesting point cloud isn't as sparse. But then you'd definitely want to view it as a TSP problem anyway.

Merovius··on Using Hilbert Curves to 100% Zelda
I have added a section about this question to the post. Let me know what you think :)
Merovius··on Using Hilbert Curves to 100% Zelda
Given that this wasn't about actually walking the map, but about just finding the locations still missing (and those locations where few and sparse), this really isn't necessary.

It would be, if you'd want to do a speedrun, though.

Merovius··on Using Hilbert Curves to 100% Zelda
Basically, what others have replied is true. But, in essence, yes, I now believe that this would've worked too, if you choose an appropriate discretization of the grid. Hilbert Curves probably were simply the Hammer I had lying around. In the end, it didn't really matter, given that the actual Hilbert Curve part was mostly copy-pasted, but at least it gave me the opportunity to actually use them (and learn from it).
Merovius··on Using Hilbert Curves to 100% Zelda
I have seen JSONP. But I'm not a frontend dev and in my experience the web suffers from a persistent overspecialization of terms. I didn't mention the term JSONP, because I didn't want to end up calling something JSONP just to have someone point out, that this isn't really JSONP, but floobleworp, which is when you use jQuery and add the comment-symbols to make it safe against XSS or something in that regard.

Also, I still consider JSONP an incredibly gross idea :)

← PreviousPage 4 of 8Next →