HNHacker News
TopNewBestAskShowJobs

Merovius

729 karma · joined June 14, 2015

submissionscomments
Merovius··on Generic interfaces
> I didn't realize how important order was to type inference.

I was unclear, I'm afraid. You can reorder the type parameters, it just changes which of them you need to specify: https://go.dev/play/p/oDIFl3fZiPl

The point is that you can only leave off elements from the end of the list, to have them automatically inferred.

> Are there any real packages out there using these techniques?

I think so far, the usage of generics for containers in Go is still relatively sparse, in public code. I think in part that is because the documentation of how to do that is relatively sparse. That is part of the motivation for the post, to have a bit of somewhat official documentation for these things, so they become more widely known.

The standard library is just starting to add generic containers: https://github.com/golang/go/issues/69559 And part of that is discussing how we want to do things like this: https://github.com/golang/go/issues/70471

That being said, I have used the pointer receiver thing in my dayjob. One example is protobuf. We have a generic helper to set a protobuf enum from the environment. Because of how the API was designed, that required a pointer receiver constraint.

Merovius··on (On | No) Syntactic Support for Error Handling
Oh and to be clear: I didn't say "look at this issue, most people clearly prefer the status quo". I just said that given this issue, making the claim that the status quo is objectively bad is hard to justify. I said that its badness is clearly subjective.

That is, I criticized the strength of the original claim. I didn't try to make an equally strong opposite claim.

Merovius··on (On | No) Syntactic Support for Error Handling
> (that is the reason the people spend years to solve it)

I don't think anyone actually spend years trying to solve it. It's just that over the years, many people have tried to solve it - each for a grand total of maybe a week or so. If you look at the list, you'll see a lot of different proposal authors: https://seankhliao.com/blog/12020-11-23-go-error-handling-pr... Most of these do not post any other issues and many of those don't even respond in the discussion to their own proposals.

It's a thing that a lot of people coming to the language get frustrated by, think "here is an obvious way to make this better" and file a (usually half-baked) proposal about. It's not a thing that people spend years of focused effort on to polish into something that works.

Compare that to generics: Not only did Ian file a proposal about that roughly every year. The final design also had over a year of intense discussion, with at least a dozen or two consistent participants (and a hundred or so occasional ones). With at least three or four direct iterations.

Error handling is something that a lot of people care a little about.

Merovius··on (On | No) Syntactic Support for Error Handling
It doesn't really contradict the survey all that much. 13% of respondents said that error handling is the biggest issue. That leaves 87%, which can rank anywhere from "it's an issue, but not the biggest" through "it's a minor nuisance" through "I don't care" up to "I actively like the status quo". We can only guess about the distribution.

And yes, I agree that the survey is a better source of data, generally. But I will also say that it intentionally asks as broad a definition of "Go user" as possible. Meaning it also (intentionally) asks people who might use Go every once in a while at work. And a good chunk of respondents are newcomers. These groups are more likely to identify this as a problem. While people who are active on GitHub tend to bias towards people who use it as a daily driver and are much more used to its idioms.

The data is mixed. I fully acknowledge that. But anecdotally, there seems to be a pretty clear pattern that people who come new to the language complain about this, but then get used to it and at the point where they become active in the community, they prefer the status quo. I don't think the experience of newcomers should be dismissed, but I also think it should be acknowledged that it's something most people get used to.

Merovius··on (On | No) Syntactic Support for Error Handling
> But is know that the current way of Go (that is a insignificant improvement over the C way) sucks and ANY of the other ways are truly better […]

This is a bold statement for something so subjective. I'll note that the proposal to leave the status quo as-is is probably one of the most favorably voted Go proposals of all time: https://github.com/golang/go/issues/32825

Go language design is not a popularity contest or democracy (if nothing else because it is not clear who would get a vote). But you won't find any other proposal with thousands of emoji votes, 90% of which are in favor.

I get the criticism and I agree with it to a degree. But boldly stating that criticism as objective and universal is uninformed.

Merovius··on (On | No) Syntactic Support for Error Handling
Except if your traits are not dyn-compatible. Which I believe a lot of Rust's traits are not. That restriction is specifically why Go does not allow methods to have extra type parameters: To make it possible for the language implementation to choose its own tradeoff between monomorphization and boxing.

So I don't think you can say that this has nothing to do with the type system. Here is a restriction in the Go type system that was specifically introduced to allow a broad range of implementation choices. To avoid being forced to choose slow compilers or slow code: https://research.swtch.com/generic

The Go type system and the way it does generics is directly designed to allow fast compile times.

Merovius··on Amazon's Kindle Direct Publishing is a dystopian nightmare
I can blame the evil overloads for building a monopoly which then becomes a juicy target for scammers. Just like block chains are effectively "the mother of all zero-day bug-bounties", so are monopolies the mother of all algorithm-exploitation bug-bounties.
Merovius··on Constraining Complexity in Go Generics
A supplementary post to my talk at GopherConAU 2023, about a design problem with NP-completeness encountered in the discussions about Go generics.
Merovius··on Go: What we got right, what we got wrong
That depends. C function call overhead for Go is quite large (it needs to allocate a larger stack, put it on its own thread and prevent pre-emption) and possibly larger than for CPython, which relies on calling into C for pretty much everything it does, so obviously has that path well-optimized.

So I wouldn't be surprised if, for some use cases, Python calling C in a tight loop could outperform Go.

Merovius··on Go: What we got right, what we got wrong
> its creators explicitly said their goal was to replace C++

I think that is a far clearer goal if you look at C++ as it is used inside Google. If you combine the Google C++ style guide and Abseil, you can see the heritage of Go very clearly.

Merovius··on Death by vegetable oil: What the studies say (2020)
The Author of this article is the founder of a startup trying to make "cultured oil" happen. Not a particularly trustworthy and neutral source for "the studies".

He's certainly not going to be very motivated to tell y'all about studies showing that he is staking his time and money and reputation on a nonsense product. It's embarrassing that y'all upvoted this.

Merovius··on The Twitter Files Part 2: Twitter's Secret Blacklists
> I'm also slightly concerned over how blase "hackers" here on this site are treating the news. All around us are these huge, easy-to-abuse, global influence platforms with cozy backchannels to the most powerful bureaucratic state (US govt) that we've ever seen. And yet many comments I've seen so far are along the lines of, "No worries, this stuff happens all the time and is totally normal and okay. Move along now!" I would have expected more skepticism, cynicism and backlash from this crowd. Am I wrong?

I don't think you are wrong. I do think this is a powerful tool, that should be scrutinized. But I also can't think of any better alternative. So, in the meantime, ISTM that talking about how it's talked about (as a great conspiracy and revelation, when it's well-known and the best known solution to a problem we have) seems the right way to go about it.

And note that not so long ago Musk himself said that this solution is what he wants for Twitter¹.

I just think when talking about the "Twitter Files", the more interesting story is how Musk is spreading disinformation and propaganda to increase his own wealth and power and how supposed journalists are uncritically helping him do it.

[1] https://twitter.com/whstancil/status/1601020232994201601

Merovius··on Why don’t we do email verification in reverse?
> In both cases, the proof is the same: “email verification” means “the user controls an email address.”

No. In one case the proof is "the user receives E-Mails under this address" and in the other it is "the user can send E-Mails under this address".

The service is generally interested in proving the first. For recovery, service-related notifications and for unsolicited marketing. So all the things mentioned in making the "normal" flow undesirable, are actually exactly what the service owner wants to protect against. If their E-Mails don't get to you because they end up in spam or just get dropped by a misconfigured Mailserver, they can't spam you and you won't be able to use this account for recovery.

I agree that the reverse flow is easier (though TBF, mailto links also require the user to have set them up to work, which not all users have on all their devices). But I don't think that's where the incentives align.

Merovius··on Operator constraints in Go
Even though you are being snarky and intentionally obnoxious: I even thought about that, yes. If unicode would allow to use red and green as skin tone modifiers, I would've done it. Except I probably wouldn't have used red and green, but red and blue or something. Because color blindness is a thing.

Look, I accept the criticism that the table is a bit hard to read. I thought about it and it's still the way I like it best. And it's the most low-stakes thing possible. It doesn't matter if it is slightly hard to read. It's my personal blog. "I like it best this way" is enough said.

Merovius··on Operator constraints in Go
I considered both. The issue I'm having is that "yes" and "no" is semantically wrong - or rather, semantically uninteresting. The interesting question is if a particular mechanism is "good" or "bad" in a particular way. For "boilerplate types", a "yes" is bad. For "custom order", a "yes" is good.

Writing "yes" or "no" (or using checkmarks and crosses) means I either have to put it on the reader to do that extra step of inference. Or that I have to re-phrase every item to be aligned in this way, while staying snappy. Or I could write "good" and "bad", of course, which seemed… overly simplistic.

Anyways, I did think about all of this and it was a conscious decision. For better or for worse. And I'm okay with it, criticism notwithstanding :)

Merovius··on Operator constraints in Go
Personally, I very much dislike that this makes the zero value of `SearchTree[T]` not useful. I personally feel that anything which only handles data (as opposed to something like an os.File) shouldn't require explicit initialization.

I genuinely think I might personally converge on the `Comparator[T]` approach only (at least for types), for that reason.

Merovius··on Operator constraints in Go
Note that the article targets people writing generic code, not consuming it. So it's not really about what you want to sort. It's about what (and how) you want to support with your sorting algorithm.

As for that use-case: Go generics currently don't have a way to constrain on struct fields. So that will always have to be done with some sort of custom comparison function written by the user of your code, which returns the appropriate field.

Merovius··on Operator constraints in Go
> How do float32 and float64 satisfy constraints.Ordered?

Well, the simple answer is that constraints.Ordered is a type set which lists them: https://pkg.go.dev/golang.org/x/exp/constraints#Ordered

The other answer is of course, that float32 and float64 have a < operator, so every type listed in constraints.Ordered does, so you can use the < operator on a type parameter constrained by constraints.Orderded.

The real question you seem to be asking though, is "how does Go support < on float32 and float64 if the IEEE-754 standard says that NaN are not comparable". I can't comprehensively answer that, because I don't know that standard well enough. But for == the answer is that == is supported on floats and x == y is always false if either is NaN. Empirically, the same seems to be true for NaN <= NaN: https://go.dev/play/p/hB9CnrzpAVq

In any case, Wikipedia claims that IEEE-754 defines in fact an ordering, which is the one Go is going to use use: https://en.wikipedia.org/wiki/IEEE_754#Total-ordering_predic...

Merovius··on Calculating Go type sets is harder than you think
> So far, Rust seems to have gotten it right by essentially copying Haskell.

FWIW I've used Rust for a bit and I disagree that they "got it right". I'm not saying Rust is bad, I like the language. But it's not as if their generics implementation does not have issues. It's just that they are different issues.

Merovius··on Calculating Go type sets is harder than you think
> It is indeed accepted if it's there by itself, but it is rejected if you try to use the interface, which is what function f does:

You can't use it as a type, but you can use it as a constraint: https://go.dev/play/p/LnmudHIjAoQ

Of course, you can then not actually instantiate that function (as the type set is empty). But using concrete types in interfaces is very possible. And it's indeed why the |-operator was introduced. It allows you to use operators: https://go.dev/play/p/I3eMDBwIcHA

Merovius··on Calculating Go type sets is harder than you think
> To be clear here, the tradeoff being made is that it is more important that the compiler is fast than that it is able to tell programmers about clear bugs in their code.

I'm not sure that's entirely true. Or it seems at least misleading.

"Fast" here means "guaranteed to finish before the heat death of the universe", in the worst case.

And as I'm trying to explain in the post, it is easier to explain clear bugs to the programmer, if you don't have to rely on solving NP-complete problems. NP-complete problems are notoriously hard to report errors for, which the user understands.

Merovius··on Calculating Go type sets is harder than you think
There are two reason why the compiler would need to check: 1. Because it makes for a better developer experience, if you get early feedback about your code being wrong. And 2. because type-checking a generic function requires you to check that an operation is allowed for all types in a type set. If you write func F[T C](a, b T) T { return a + b }, the compiler needs to check that all types in C have a + operator. If the type set of C is empty, then that's true - all types in the empty set have the + operator.
Merovius··on GDPR penalty for passing on of IP address to Google by using Google Fonts
I'm confused about the text. It is not obvious, what the defendant actually did.

The assumption from most people seem to be that they used a `<script>` tag or the like, with a Google URL. But the text does not imply that. On the contrary, it repeatedly uses the word "weitergabe" and "weiterleitung" ("forwarding"), which is just not accurate for this process - it seems to imply that the defendant actively made a connection to Google and sending the IP over it.

Of course, this might just be an artifact of the legalese and non-technical phrasing of the verdict. But does anyone know what actually happened, on a technical level?

Merovius··on GDPR penalty for passing on of IP address to Google by using Google Fonts
> Easiest way to deal with this is to self-host the videos.

For most videos, this would be a copyright violation. i.e. there are now two laws which prevent reasonable technological solutions, making it harder for most people to host and produce content - favoring the already heavily advantaged big companies.

Merovius··on Does the Amazon provide 20% of our oxygen?
> This reminds me, as we should all be reminded on a regular basis, the bulk of the things you read in the popular press are at best skimming the surface and at worst outright misleading due to grabbing onto one obscuring factoid instead of the most important pieces of information

FTR, this article is doing exactly that. Like, they a) divert your attention with the CO₂<->O₂ conversion (which doesn't change relative numbers in percentages of photosynthesis at all - you multiply both sides of the equation). And b) then proceeds to pretend that the Amazon eats up most of the Oxygen it produces, but the rest of the world apparently doesn't. Like, if a tree re-metabolizes 40% of the O₂ it produces, then that's also true for the 91% of O₂ produced outside the Amazon, so we still end up with the same 9% figure of all O₂ produced in the Amazon.

The article ends with the "CO₂ emission is more important". Which, again, fair. But Photosynthesis is presumably a pretty important mechanism by which CO₂ is removed from the air. So a reduction of O₂ production is equivalent to a reduction of CO₂ absorption (though you have to multiply with 2.67, don't forget!), which seems to… be a bad thing for CO₂ concentration in the air.

The gist of the article is pretty much "if you don't round and take into account maritime photosynthesis, the Amazon only produces 9% of all O₂". Which is fair. The rest is noise. It doesn't add to the argument and is just fueling the "MSM is bad!" cries…

Merovius··on Go is Google's language, not ours
I'm so tired of people purporting to speak for "the community" - especially when they diametrically oppose my own views. It feels a lot like they are co-opting me for their own agenda while simultaneously excluding me.

The things mentioned as evidence that community doesn't matter have a lot of buy-in from the community. Modules in particular are an effort that - at least from what I can tell - is heavily driven by non-Googlers (in particular Rog Pepe, Paul Jolly and Daniel Marti are people who put a lot of work into making modules actually work for practical workloads).

These kinds of pieces only make sense if you have an extremely limited view of who is or is not part of "the community" - in particular, if you throw everyone agreeing with the Go team out of that bucket.

Merovius··on A Note on SIMON-32/64 Security
Just as the only thing I can add:

> how did they come up with 2^10 number?

I'd guess common interpretation of Moore's law as a doubling of computing power every 18 months. 2002 was 17y ago, so you end up with ~11 doublings. Discrepancy can be explained by ballparking.

Merovius··on Optimizing M3: Halving Our Metrics Ingestion Latency by Forking the Go Compiler
One thing that Go does better here than I've seen in other (compiled) languages so far, is that you can literally just cd into GOROOT, do your changes and a build of your project will pick up on the changed stdlib and re-compile it on-the-fly. I pretty regularly do that as a debugging aide. Of course, it isn't just as simple with the compiler itself, you still have to re-build that one manually.
Merovius··on Go Modules in 2019
> is bound to the lowest common denominator for any chance of success.

ISTM the "lowest common denominator" is a superset of everything current language-specific package-managers support and a subset of anything a current language-agnostic package-manager supports (pretty much definitionally). So ISTM that this is a net win - easier to build than APT/DNF/Pacman… and yet more useful than npm/stack/pip/…

In particular, I don't know any currently existing language-specific package-manager that supports what I'd call the GCD of package-management (e.g. none that I can think of supports actual OS-specific installation of packages) so that clearly isn't even a requirement.

> Thus forcing everyone that needs something beyond that lowest common denominator to implement their own workarounds, thus we are again back to language package managers.

FWIW, a) part of the political and social problem is to talk more honestly about what "needing" really means and b) no, that's not at all "back to language package managers". You can have a layered design, e.g. splitting the "building" and the "installation" part, thus letting languages implement their workarounds in their dedicated building layer and letting OSes implement their workarounds in their installation layers. You just need to actually sit down and talk about the interface needed between the two (and the sets of layers actually needed, which will be >2). Which no one seems really willing to do.

Merovius··on Go Modules in 2019
> Good luck creating a package format that works across iOS, Android, Red-Hat, SuSE, Debian, Ubuntu, ..., IBM i, IBM z, Aix, HP-UX, Solaris, Windows, Zephyr, Yoctos, RTOS, Integrity, mbed, MicroEJ, BSD variants, Unisys ClearPath, VxWorks, QNX, macOS, Tizen, Jolla, ChromeOS, Fuchsia and several others that I am unaware of or was too lazy to keep adding entries for.

Can you explain why that would be a problem? It's certainly not a technical one, none of these are special when it comes to versioning or dependency management of software. I can see that there's a social/political problem - which is exactly what I'm talking about.

← PreviousPage 2 of 8Next →