HNHacker News
TopNewBestAskShowJobs

kbolino

2,386 karma · joined August 29, 2011

submissionscomments
kbolino··on My “grand vision” for Rust
This forms a closed set of types (A, B, nil -- don't forget nil!) but the compiler doesn't understand it as such and complains that the following type-switch is not exhaustive ("missing return"):

  func Foo(s SumType) bool {
    switch s.(type) {
    case A: return true      
    case B: return true
    case nil: return true
    }
  }
Also, you, the package author, may know what constitutes SumType, but the consumers of your package don't, at least not without source. Moreover, you can spread A, B, and any other implementations of SumType across many source files, making it hard to answer the question even with source. This is even a problem for the standard library, just consider go/ast and its Decl, Expr, and Stmt interfaces, none of which document what types actually implement them.
kbolino··on My “grand vision” for Rust
Go does not use LLVM at all and never has. It uses its own compiler and its own (quirky) assembler. Of course, this does not matter to most people, but LLVM compilation can be both a blessing (good interop with C/FFI) and a curse (changes to LLVM internals causing issues for languages other than C/C++).
kbolino··on UUID package coming to Go standard library
> They also failed to initially offer any automatic porting tooling which could have increased adoption.

Maybe it wasn't very good, but 2to3 was there from the start:

https://docs.python.org/3.0/library/2to3.html

kbolino··on UUID package coming to Go standard library
From nbio's README:

  For regular connection scenarios, nbio's performance is inferior to the standard library due to goroutine affinity, lower buffer reuse rate for individual connections, and variable escape issues.
From gnet's README:

  gnet and net don't share the same philosophy in network programming. Thus, building network applications with gnet can be significantly different from building them with net, and the philosophies can't be reconciled.
  [...]
  gnet is not designed to displace the Go net, but to create an alternative in the Go ecosystem for building performance-critical network services.
Frankly, I think it's unfair to argue that the net package isn't performant, especially given its goals and API surface.

However, the net/http package is a different story. It indeed isn't very performant, though one should be careful to understand that that assessment is on relative terms; net/http still runs circles around some other languages' standard approaches to HTTP servers.

A big part of why net/http is relatively slow is also down to its goals and API surface. It's designed to be easy to use, not especially fast. By comparison, there's fasthttp [1], which lives up to its name, but is much harder to work with properly. The goal of chasing performance at all costs also leads to questionable design decisions, like fiber [2], based on fasthttp, which achieves some of its performance by violating Go's runtime guarantee that strings are immutable. That is a wild choice that the standard library authors would/could never make.

[1]: https://pkg.go.dev/github.com/valyala/fasthttp

[2]: https://pkg.go.dev/github.com/gofiber/fiber/v3

kbolino··on Wikipedia was in read-only mode following mass admin account compromise
I picked hosting because it's a line item that exists across all of their budgets, it's a rough proxy for a web business's non-salary expenses, it's a big part of what you think you're donating to based upon Wikipedia's own language in their fundraising drives, and if nothing else, it's way more forgiving to the growth of their expenses than consumer price inflation is.

Ultimately every person has to decide for themselves whether they think WMF is a worthy recipient for their donations, but it is in no way operating on a shoestring budget nor staffed by volunteers anymore.

kbolino··on Wikipedia was in read-only mode following mass admin account compromise
There are a couple of ways to approach this information. One is to compare to the past. For example, comparing with 2008-2009 [1], they now spend 3.75 times as much on hosting, but 48 times as much on salaries, illustrating a more-than-tenfold relative growth in salaries compared to hosting. While hosting is not now nor ever was their only relevant expense, it is a good anchor point.

Another key difference over the last 15 years has been the introduction of awards and grants, which didn't exist then but now comprise $26.8M (15%) of their expenditures. This is where most of the ideological/controversial spending actually goes, rather than the salaries per se, but even more to the point, this one line item is more than 3 times their entire inflation-adjusted budget from 15 years ago ($5.6M times 150% CPI = $8.4M) and is still more than if we adjusted their entire budget using the hosting cost as an index ($5.6M times 3.75 = $21M).

[1]: https://upload.wikimedia.org/wikipedia/commons/a/a4/WMF_Annu...

kbolino··on Wikipedia was in read-only mode following mass admin account compromise
Where and how they spent their money is on p. 21 of this PDF [1] which can be obtained from this official source [2]. This is just a high-level breakdown, but it does illustrate that, for example, more than twice as much is spent on "Donation processing expenses" ($7.5M) as "Internet hosting" ($3.1M), and that the largest line item, by far, is "Salaries and benefits" ($106M).

[1]: https://wikimediafoundation.org/wp-content/uploads/2025/04/W...

[2]: https://wikimediafoundation.org/annualreports/2023-2024-annu...

kbolino··on Better JIT for Postgres
It is not always necessary to explicitly use prepared statements, though. For example, the pgx library for Go [1] and the psycopg3 library for Python [2] will automatically manage prepared statements for you.

[1]: https://pkg.go.dev/github.com/jackc/pgx/v5#hdr-Prepared_Stat...

[2]: https://www.psycopg.org/psycopg3/docs/advanced/prepare.html

kbolino··on Apple Studio Display and Studio Display XDR
The Apple monitor will likely have better speakers, and I'm not even sure the others will have microphones at all. Apple also does a better job with color accuracy/consistency, at least historically. There's still a sizeable markup, but it's not entirely for nothing.

Back in the day (~15 years ago), when 4K monitors were unheard of and even Apple's high-end displays were still 1440p, you could get a bottom-dollar monitor using one of their panels (e.g. Yamakasi Catleap Q270) for about a third of the price. However, it came with no amenities, a single connector (dual-link DVI only), a questionably legal power cable, and no built-in scaling. The vendors, presumably to prevent refunds, even asked for your graphics card model before selling it to you, because it wouldn't work with low-end cards. Oh, and there were very few in the U.S., so you were typically getting them shipped straight from abroad, customs duties and all.

We've definitely come a long way.

kbolino··on Why Go Can't Try
Go 1.26 just added new(expr) which simplifies passing values to places that expect pointers.

The old guard is slowly stepping away, for good or ill. QoL changes are not off the table, but they do have to fit into the language.

kbolino··on Why Go Can't Try
There are cases where privileging the first alternative makes sense (like Maybe[T] = None|T with None = struct{} e.g.), and there are cases where it doesn't (like Either[L,R] = L|R). There has been an extensive amount of discussion about a number of different proposals, e.g. https://github.com/golang/go/issues/54685, https://github.com/golang/go/issues/57644, etc., but so far, much like "better" error handling, no workable consensus has yet emerged.
kbolino··on Why Go Can't Try
This is true, but it feels like a mistake. It's too late to change now, of course, but I feel like (0, nil) and (!=0, !=nil) should both have been forbidden. The former is "discouraged" now, at least. It does simplify implementations to allow these cases, but it complicates consumers of the interface, and there are far more of the latter than the former.
kbolino··on Why Go Can't Try
The author doesn't touch on it, but the bigger problem with things like Foo|Bar as an actual type (rather than as a type constraint) is that every type must have a default/zero value in Go. This has proven to be a difficult problem for all of the proposals around adding sum types, whether they're used as errors or otherwise. For example, to support interface{Foo|Bar} as a reified type, you'd have to tolerate the nil case, which means you either couldn't call any methods even if they're common to Foo and Bar, or else the compiler would have to synthesize some implementation for the nil case, which would probably have to just panic anyway. And an exhaustive type-switch would always have to have "case nil:" (or "default:") and so on.
kbolino··on Allocating on the Stack
The ability to grow without copying is already part of how slices work. Every slice is really a 3-word tuple of pointer, length, and capacity. If not explicitly set with make, the capacity property defaults to a value that fills out the size class of the allocation. It just so happens that, in this case, the size of the Task type doesn't allow for more than 1 value to fit in the smallest allocation. If you were to do this with a []byte or []int32 etc., you would see that the capacity doesn't necessarily start at 1: https://go.dev/play/p/G5cifdChGIZ
kbolino··on Why the KeePass format should be based on SQLite
Whole-file encryption with authentication is also more tamper-resistant. Basically the only thing an adversary can get away with there is rolling back the entire file to a previous version.

Whereas, any incrementally encrypted format has the additional risk of piecewise manipulations. For example, while SQLCipher authenticates each page, it doesn't authenticate the entire file, allowing for pages to be deleted, reordered, or duplicated (though duplication is easy to detect since each page has its own IV). The end result will generally just be a corrupted database, which will probably get detected by PRAGMA integrity_check, but compared to KDBX, this will not be detected by default nor is it guaranteed to be detectable at all.

kbolino··on Why the KeePass format should be based on SQLite
SQLCipher is not SQLite.

A key aspect of SQLite's development model is its proprietary test suite. As far as I can tell, the SQLCipher developers do not have access to those tests.

This is not to say they aren't doing the best with what they've got, but SQLCipher is a fork of SQLite, and the scope of the changes they must make, no matter how conservatively they try to make them, should lead to a full re-test of the entire product, which they cannot do.

EDIT: I don't want this to come off as spreading FUD. The SQLCipher developers do a good job of laying out their development methodology, the relative (un-)testability of their product vs. SQLite, and other tradeoffs pretty well in the repository's README: https://github.com/sqlcipher/sqlcipher?tab=readme-ov-file#sq...

kbolino··on Why the KeePass format should be based on SQLite
A ZIP file with solid encryption (i.e., the archive is encrypted as a single whole) has all of the same tradeoffs as a KDBX file as far as incremental updates are concerned.

A ZIP file with incremental encryption (i.e., each file is individually encrypted as a separate item) has its own problems. Notably: the file names are exposed (though this can be mitigated), the file metadata is not authenticated, and the central directory is not authenticated. So sure, you can read that index, but you can't trust it, so what good is it doing? Also, to support incremental updates, you'd either have to keep all the old versions of a file around, or else remove them and end up rewriting most/all of the archive anyway. It's frankly just not a very good format.

kbolino··on -fbounds-safety: Enforcing bounds safety for C
It's good info, and I wouldn't rush a migration off of SPARC systems if I was already using them, but slow death is still death. It was already worrying that workstations were killed off by Sun before the Oracle acquisition; it seems quite clear that no one has been serious about spreading adoption of the architecture for more than two decades now.
kbolino··on -fbounds-safety: Enforcing bounds safety for C
The feature is only on SPARC, not x86. Oracle killed in-house SPARC development in 2017, and they abandoned OpenSPARC after they acquired Sun, so it's effectively a dead architecture. The software won't work without the hardware to run it on.
kbolino··on 15 years of FP64 segmentation, and why the Blackwell Ultra breaks the pattern
This isn't really true, and it wouldn't be a big deal even if it was.

Die areas for consumer card chips are smaller than die areas for datacenter card chips, and this has held for a few generations now. They can't possibly be the same chips, because they are physically different sizes. The lowest-end consumer dies are less than 1/4 the area of datacenter dies, and even the highest-end consumer dies are only like 80% the area of datacenter dies. This implies there must be some nontrivial differentiation going on at the silicon level.

Secondly, you are not paying for the die area anyway. Whether a chip is obtained from being specially made for that exact model of GPU, or it is obtained from being binned after possibly defective areas get fused off, you are paying for the end-result product. If that product meets the expected performance, it is doing its job. This is not a subsidy (at least, not in that direction), the die is just one small part of what makes a usable GPU card, and excess die area left dark isn't even pure waste, as it helps with heat dissipation.

The fact that nVidia excludes decent FP64 from all of its prosumer offerings (*) can still be called "artificial" insofar as it was indeed done on purpose for market segmentation purposes, but it's not some trivial trick. They really are just not putting it into the silicon. This has been the case for longer than it wasn't by now, even.

* = The Quadro line of "professional" workstation cards nowadays are just consumer cards with ECC RAM and special drivers

kbolino··on 15 years of FP64 segmentation, and why the Blackwell Ultra breaks the pattern
Has FP80 ever existed anywhere other than x87?
kbolino··on AVX2 is slower than SSE2-4.x under Windows ARM emulation
The rarity of use is a chicken-egg problem, though. The hardware makers consider it a waste because the software doesn't use it, and the software makers won't use it because it's not widely supported enough. Apple and Qualcomm not supporting it at all on any of their hardware tiers just exacerbates it. I think this is a good explanation for why mobile devices lack it, and even why say a MacBook Air or Mac Mini lacks it, but not why a MacBook Pro or Mac Studio lacks it.

It does seem like server hardware is adopting SVE at least, even if it's not always paired with wider registers. There are lots of non-math-focused instructions in there that benefit many kinds of software that isn't transferable to a GPU.

kbolino··on AVX2 is slower than SSE2-4.x under Windows ARM emulation
This is a bit short-sighted. Yes, it is kinda tricky to get right, and a number of programming languages are quite behind on good SIMD support (though many are catching up).

SIMD is not limited to mathy linear algebra things anymore. Did you know that lookup tables can be accelerated with AVX2? A lot of branchy code can be vectorized nowadays using scatter/gather/shuffle/blend/etc. instructions. The benefits vary, but can be significant. I think a view of SIMD as just being a faster/wider ALU is out of date.

kbolino··on AVX2 is slower than SSE2-4.x under Windows ARM emulation
Part of the reason, I think, is that Qualcomm and Apple cut their teeth on mobile devices, and yeah wider SIMD is not at all a concern there. It's also possible they haven't even licensed SVE from Arm Holdings and don't really want to spend the money on it.

In Apple's case, they have both the GPU and the NPU to fall back on, and a more closed/controlled ecosystem that breaks backwards compatibility every few years anyway. But Qualcomm is not so lucky; Windows is far more open and far more backwards compatible. I think the bet is that there are enough users who don't need/care about that, but I would question why they would even want Windows in the first place, when macOS, ChromeOS, or even GNU/Linux are available.

kbolino··on AVX2 is slower than SSE2-4.x under Windows ARM emulation
Yeah, the extensions exist, and as pointed out by a sibling comment to yours, have been implemented in supercomputer cores made by Fujitsu. However, as far as I know, neither Apple nor Qualcomm have made any desktop cores with SVE support. So the biggest reason there's no desktop software for it is because there's no hardware support.
kbolino··on AVX2 is slower than SSE2-4.x under Windows ARM emulation
I suspected this was because the vector units were not wide enough, and it seems that is the case. AVX2 is 256-bit, ARM NEON is only 128-bit.

The big question then is, why are ARM desktop (and server?) cores so far behind on wider SIMD support? It's not like Intel/AMD came up with these extensions for x86 yesterday; AVX2 is over 15 years old.

kbolino··on Using go fix to modernize Go code
Go has a pretty good race detector already, and all it (usually) takes to enable it is passing the -race flag to go build/test/run/etc.
kbolino··on Major European payment processor can't send email to Google Workspace users
I'm sorry, I did not properly read and comprehend your original post. I thought you were saying "they put sensitive details in the text/plain part", implying that those details somehow only belonged in the text/html part. What you actually said was "they put somebody else's sensitive details in the text/plain part".
kbolino··on Major European payment processor can't send email to Google Workspace users
text/plain != plaintext

This is about media types, not encryption.

kbolino··on Microsoft forced me to switch to Linux
I can get a mild form of it on my M4 MBP's built-in display at "1800x1125"* but it's not nearly as noticeable as it was on the 4K external display at "2560x1440" and honestly I needed my cell phone camera zoomed in to definitively identify it, so that was more of a fishing expedition than a real problem. However, I have tried 2 different Macs, 2 different 4K monitors (both LG UltraFine also, though they differ in firmware version and color reproduction because of course they do), and 2 different interfaces (HDMI, Thunderbolt), and I can reliably replicate it under all of those combinations. I think that exact scaling factor probably has a bad interaction with the scaling algorithm. I do agree that a lot of other scalings do not produce the ringing/halo/bloom effect.

* = You have to go click "Advanced...", enable "Show resolutions as list", then when back on the main Displays page, enable "Show all resolutions", to get this and many other options -- but this is only necessary on the internal display, the external display offers "2560x1440" as a non-advanced choice

← PreviousPage 4 of 34Next →