HNHacker News
TopNewBestAskShowJobs

snuxoll

5,539 karma · joined May 23, 2013

E: stefan/at/nuxoll/dot/me

[ my public key: https://keybase.io/snuxoll; my proof: https://keybase.io/snuxoll/sigs/QHJDpM106Grm7eivaaPVuE9l38pLhv26zAHli6i6mZ8 ]

submissionscomments
snuxoll··on COM Like a Bomb: Rust Outlook Add-in
While they're not "the same", classic COM (or OLE? the whole history is a mess) did actually have ProgIDs, and WinRT introduces proper "classes" and namespaces (having given up global registration for everything but system provided API's) with proper "names" (you can even query them at runtime with IInspectable::GetRuntimeClassName).

Microsoft tried to do a lot with COM when they first released it, it wasn't just a solution for having a stable cross-language ABI, it was a way to share component libraries across multiple applications on a system, and a whole lot more.

> but that also wouldn't have flown when COM was invented and resources overall were much more scarce than they are today.

And this ultimately is the paradox of COM. There were good ideas, but given Microsoft's (mostly kept) promise of keeping old software working the bad ones have remained baked in.

snuxoll··on COM Like a Bomb: Rust Outlook Add-in
You are absolutely right on all counts, although XPC/Binder/D-Bus aren't really something to compare against the core of COM (the ABI model), and I think many Windows developers would have some unkind things to say about DCOM.
snuxoll··on COM Like a Bomb: Rust Outlook Add-in
> Don't all of the Windows DirectX gaming interfaces use COM? And isn't AAA gaming performance critical?

Yes, on both counts. You will also, on average, be making fewer calls to ID3D12CommandQueue methods than one would think - you'd submit an entire vertex buffer for a model (or specific components of it that need the same pipeline state, at least) at once, allocate larger pools of memory on the GPU and directly write textures to it, etc.

This is the entire design behind D3D12, Vulkan, and Metal - more direct interaction with the GPU, batching submission, and caching command buffers for reuse.

When I'm talking about "critical sections" of code, I mean anything with a tight loop where you can reasonably expect to pin a CPU core with work. For a game, this would be things like creating vertex buffers, which is why all three major API's take these as bare pointers to data structures in memory instead of requiring discrete calls to create and populate them.

snuxoll··on COM Like a Bomb: Rust Outlook Add-in
What do you mean by "owned" strings?

WinRT, which is ultimately just an evolution of COM, has HSTRING which can own the data inside it (as well as contain a reference to an existing chunk of memory with fast-pass strings).

snuxoll··on COM Like a Bomb: Rust Outlook Add-in
As somebody who's been, for whatever reason, toying around with writing a COM-style ABI layer in Rust, there's a lot of good ideas in there and I think a lot of the hatred comes from the DLL hell that was spawned by registration; along with the, unfortunately necessary, boilerplate.

Virtual dispatch absolutely has an overhead, but absolutely nobody in their right mind should be using COM interfaces in a critical section of code. When we're talking things like UI elements, HTTP clients, whatever, the overhead of an indirect call is negligible compared to the time spent inside a function.

The one thing I'm personally trying to see if there's any room for improvement on in a clean slate design, is error handling / HRESULT values. Exceptions get abused for flow control and stack unwinding is expensive, so even if there was a sane way to implement cross-language exception handling it's a non starter. But HRESULT leads to IErrorInfo, ISupportErrorInfo, thread local state SetErrorInfo/GetErrorInfo, which is a whole extra bunch of fun to deal with.

There's the option of going the GObject and AppKit route, using an out parameter for an Error type - but you have to worry about freeing/releasing this in your language bindings or risk leaking memory.

snuxoll··on Microsoft increases Office 365 and Microsoft 365 license prices
A 5% increase is still a sizable when you consider the number of licenses that even an SMB may have. I don't deal with our MS licensing directly at $DAYJOB, but we've got something like 1300+ employees most (all?) of whom have M365 E5 licenses, that adds up to (roughly) an extra $4K/mo or $48K/yr when it comes time to renew our annual licensing.

Is it going to break the bank and send us into a financial death spiral? Absolutely not. But, you get enough companies deciding to jack up pricing at around the same time and it comes out to a significant increase in our lights-on budget - death by a million cuts hurts just as much as Broadcom raking us over the coals with VMWare license increases.

snuxoll··on Thoughts on Go vs. Rust vs. Zig
I am fully aware of how fmt.Errorf works as well as what's inside the `errors` package in the Golang stdlib, as I do work with the language regularly.

In practice, this ends up with several issues (and I'm just as guilty of doing a bunch of them when I'm writing code not intended for public consumption, to be completely fair).

fmt.Errorf is stupid easy to use. There's a lot of Go code out there that just doesn't use anything else, and we really want to make sure we wrap errors to provide 'context' since there's no backtraces in errors (and nobody wants to force consuming code to pay that runtime cost for every error, given there's no standard way to indicate you want it).

errors.New can be used to create very basic errors, but since it gives you a single instance of a struct implementing `error` there's not a lot you can do with it.

The signature of a function only indicates that it returns `error`, we have to rely on the docs to tell users what specific errors they should expect. Now, to be fair, this is an issue for languages that use exception's - checked exceptions in Java notwithstanding.

Adding a new error type that should be handled means that consumers need to pay attention to the API docs and/or changelog. The compiler, linters, etc don't do anything to help you.

All of this culminates to an infuriating, inconsistent experience with error handling.

snuxoll··on It’s time to free JavaScript (2024)
If you are legally authorized to sign on behalf of a business you can sign court filings for it.
snuxoll··on Thoughts on Go vs. Rust vs. Zig
Important to note that .context() is something from `anyhow`, not part of the stdlib.
snuxoll··on Thoughts on Go vs. Rust vs. Zig
I don't really see it as any more or less verbose.

If I return Result<T, E> from a function in Rust I have to provide an exhaustive match of all the cases, unless I use `.unwrap()` to get the success value (or panic), or use the `?` operator to return the error value (possibly converting it with an implementation of `std::From`).

No more verbose than Go, from the consumer side. Though, a big difference is that match/if/etc are expressions and I can assign results from them, so it would look more like

    let a = match do_thing(&foo) {
      Ok(res) => res,
      Err(e) => return e
    }
instead of:

     a, err := do_thing(foo)
     if err != nil {
       return err // (or wrap it with fmt.Errorf and continue the madness
                  // of stringly-typed errors, unless you want to write custom
                  // Error types which now is more verbose and less safe than Rust).
    }
I use Go on a regular basis, error handling works, but quite frankly it's one of the weakest parts of the language. Would I say I appreciate the more explicit handling from both it and Rust? Sure, unchecked exceptions and constant stack unwinding to report recoverable errors wasn't a good idea. But you're not going to have me singing Go's praise when others have done it better.

Do not get me started on actually handling errors in Go, either. errors.As() is a terrible API to work around the lack of pattern matching in Go, and the extra local variables you need to declare to use it just add line noise.

snuxoll··on Thoughts on Go vs. Rust vs. Zig
Especially since the second example only gives you a stringly-typed error.

If you want to add 'proper' error types, wrapping them is just as difficult in Go and Rust (needing to implement `Error` in Go or `std::Error` in Rust). And, while we can argue about macro magic all day, the `thiserror` crate makes said boilerplate a non-issue and allows you to properly propagate strongly-typed errors with context when needed (and if you're not writing library code to be consumed by others, `anyhow` helps a lot too).

snuxoll··on Thoughts on Go vs. Rust vs. Zig
> Beyond these concerns, I also don't love enums for errors because it means adding any new error type will be a breaking change. I don't love the idea of committing to that, but maybe I'm overthinking?

Is it a new error condition that downstream consumers want to know about so they can have different logic? Add the enum variant. The entire point of this pattern is to do what typed exceptions in Java were supposed to do, give consuming code the ability to reason about what errors to expect, and handle them appropriately if possible.

If your consumer can't be reasonably expected to recover? Use a generic failure variant, bonus points if you stuff the inner error in and implement std::Error so consumers can get the underlying error by calling .source() for debugging at least.

> By contrast, I just wrap Go errors with `fmt.Errorf("opening file `%s`: %w", filePath, err)` and handle any special error cases with `errors.As()` and similar and move on with life. It maybe doesn't feel _elegant_, but it lets me get stuff done.

Nothing stopping you from doing the same in Rust, just add a match arm with a wildcard pattern (_) to handle everything but your special cases.

In fact, if you suspect you are likely to add additional error variants, the `#[non_exhaustive]` attribute exists explicitly to handle this. It will force consumers to provide a match arm with a wildcard pattern to prevent additions to the enum from causing API incompatibility. This does come with some other limitations, so RTFM on those, but it does allow you to add new variants to an Error enum without requiring a major semver bump.

snuxoll··on Micron Announces Exit from Crucial Consumer Business
I'm not even talking about RT, specifically, but overall production quality. Increased texture detail, higher-poly models, more shader effects, general environmental detail, the list goes on.

These massive production budgets for huge, visually detailed games, are causing publishers to take fewer creative risks, and when products inevitably fail in the market the studios get shuttered. I'd much rather go back to smaller teams, and more reasonable production values from 10+ years ago than keep getting the drivel we have, and that's without even factoring in how expensive current hardware is.

snuxoll··on The RAM shortage comes for us all
Just because Nvidia happily sells people discrete GPU's, DGX systems, etc., doesn't mean they would turn down a company like OpenAI paying them $$$ for just the packaged chips and the technical documentation to build their own PCBs; or, let OpenAI provide their own DRAM supply for production on an existing line.

If you have a potentially multi-billion dollar contract, most businesses will do things outside of their standard product offerings to take in that revenue.

snuxoll··on Micron Announces Exit from Crucial Consumer Business
The literal multi-million dollar question that executives have never bothered asking: When is it enough?

Do I, as a player, appreciate the extra visual detail in new games? Sure, most of the time.

But, if you asked me what I enjoy playing more 80% of the time? I'd pull out a list of 10+ year old titles that I keep coming back to, and more that I would rather play than what's on the market today if they only had an active playerbase (for multiplayer titles).

Honestly, I know I'm not alone in saying this: I'd rather we had more games focused on good mechanics and story, instead of visually impressive works that pile on MTX to recoup insane production costs. Maybe this is just the catalyst we need to get studios to redirect budgets to making games fun instead of spending a bunch of budget on visual quality.

snuxoll··on IBM CEO says there is 'no way' spending on AI data centers will pay off
Spinning rust and fans are the outliers when it comes to longevity in compute hardware. I’ve had to replace a disk or two in my rack at home, but at the end of the day the CPUs, RAM, NICs, etc. all continue to tick along just fine.

When it comes to enterprise deployments, the lifecycle always revolves around price/performance. Why pay for old gear that sucks up power and runs 30% slower than the new hotness, after all!

But, here we are, hitting limits of transistor density. There’s a reason I still can’t get 13th or 14th gen poweredge boxes for the price I paid for my 12th gen ones years ago.

snuxoll··on Do the thinking models think?
> The article conjectures that humans reason from ideas to symbols while LLMs go from symbols to ideas, but couldn't that just be a post hoc interpretation we have for how our ideas come to our brain?

There's probably a lot to be said about people who primarily think with an internal monologue, versus those that do not, as well.

I, to the best of my own abilities to detect it, do not seem to have a more abstract, non-lingual thought process - I can't 'picture' things in my head like other people reportedly do. When I have an 'idea', it simply doesn't materialize 'in my mind' in any other way.

I, also, would not argue that LLM's share a human-like thought process. But I think saying that human thought requires some abstract idea to symbol translation isn't quite right, either.

snuxoll··on Flight disruption warning as Airbus requests modifications to 6k planes
The reality is that CRM is still the most important factor required to have a reasonable chance of turning what would otherwise be a catastrophic aviation incident into something that people walk away from. Systems do fail, when they do it's up to the crew to enact memory items as quickly as possible and communicate with each other like they are trained to.

Unfortunately, sometimes they also fail in ways that even a trained crew isn't able to recover the aircraft. That could be a failure that wasn't anticipated, training that was inadequate, design flaws, the human element, you name it. Actions of the crew being put in an accident report isn't an assignment of blame, it's a statement of facts - the recommendations that come from those facts are all that matters.

snuxoll··on Samsung's 60% DRAM price hike signals a new phase of global memory tightening
> it's a completely different protocol than PCIe.

Wrong. It is still just NVMe over PCIe like every other modern SSD form factor.

snuxoll··on Samsung's 60% DRAM price hike signals a new phase of global memory tightening
There's not a difference between "consumer" DRAM and "enterprise" DRAM at the silicon level, they're cut from the same wafers at the end of the day.
snuxoll··on Android/Linux Dual Boot
Yeah, the requirement to build and provide device trees for most mobile devices is the huge issue. For all of the garbage we have gotten from buggy ass ACPI tables on assorted PC’s, it’s absolutely true that it solved a lot of headaches with hardware discovery/enumeration.

It’s really too bad that ARM had adopted ACPI as part of their SystemReady certification. It does work, and not reinventing the wheel is always a wise where feasible, but I think we could absolutely push something better.

snuxoll··on Waiting for SQL:202y: Group by All
I mean, I get it, but the big problem is, again, the different phases of execution. The projections you perform with a select can be absolutely arbitrary and do crazy ass things (like do more subqueries that return scalar values, and query planners are notoriously bad at pushing these down), which is why I was trying to say SELECT before WHERE (project before filtering) may be linguistically intuitive, but full of foot guns.

Something like a ‘let’ binding after the FROM/JOIN list would make sense, though - from the query planners perspective it’s nothing more than a token substitution and everything would compile the same.

snuxoll··on Waiting for SQL:202y: Group by All
WHERE clauses are pushed down into the query planner before the SELECT list is processed, that’s why HAVING exists.

The logical order, in full, is:

FROM

WHERE/JOIN (you can join using WHERE clauses and do FROM a,b still)

SELECT

HAVING

snuxoll··on Addiction Markets
> You can't let society keep inventing new vices for profit in an uninhibited way.

I agree, but:

> It feels like a bell curve topic, where the most naive people think you should just ban all vices and have a strictly better world, the middle of the road thinks it's all down to personal fortitude, and then people who know how the sausage is made realize the level of asymmetry that exists.

There's a wide gap in beliefs of the people who "know how the sausage is made" which is why I'm guessing you didn't ascribe a certain view to them.

Realistically, I think it breaks down into three camps:

1. They agree with the other end of the curve, and think the potential harm is too great.

2. They're in on profiting from it.

3. They are open to people being free to make decisions, but think there needs to be regulations on outright predatory behavior and active enforcement of them

I don't have a problem with anybody choosing to safely engage with recreational drugs, pornography, gambling, alcohol, and a number of other vices - humans have sought these activities out for an extremely long time, and outright banning them simply (as we have seen time and time again) leads to unregulated black markets that are more harmful to society as a whole. But it feels like we've done a complete 180 and now we have barely any regulation where it's needed, late-stage capitalism at its finest.

So many states have put ID verification laws out for accessing pornography, exposing citizens to huge privacy risks in the process, but we've got casino empires draining their savings accounts and can't do anything about it? Please.

snuxoll··on Addiction Markets
The problem is this: the house always wins. Casinos, online sports books, the lottery, all of it is designed such that all but quite literally a lucky few will lose money. If you understand this properly, then, yes, there's absolutely nothing wrong with it being a form of entertainment, but that means you need to go in thinking about cost per hour instead of any notion of leaving with more than you began with.

This is why I have a huge problem with the recent development of online gambling outlets that you can access via your smartphone. In the past you had to go somewhere to gamble, it was a physical act that provided a barrier to entry. Now? You don't even need to think about it, your bank account is already linked, just spend away!

Personally, I'd rather states loosen laws and allow physical casinos be built and properly regulated than be in the current situation we have with these poorly regulated online money-siphons.

snuxoll··on IDEs we had 30 years ago and lost (2023)
Thanks, I was desperately trying to remember because I swore there was something beforehand, but It's been a very long time since I did the reading.
snuxoll··on IDEs we had 30 years ago and lost (2023)
Nope, we still have an IBM i deployment kicking around at $DAYJOB, it's running natively on POWER hardware. Way back in the days of the original OS/400 running on AS/400 hardware, IBM had the foresight to have applications compile to MI (Machine Interface) code; which is a bytecode format closer to something like LLVM IR instead of something like JVM or CLR bytecode. When a PGM object is copied or created on an IBM i system, TIMI (Technology Independent Machine Interface) takes the MI code and translates it to a native executable for the underlying platform.

We probably still have a couple of PGM objects kicking around on our modern POWER hardware that were originally compiled on an old AS/400 system, but they run as native 64-bit POWER code like everything else on the machine.

The IBM midrange line gets a lot of undue disgust these days, it's not sexy by any means, sure, but just like anything running on modern day Z/OS you know that anything you write for it is going to continue to run decades down the line. Well, as long as you limit the amount of stuff you have running on 'modern' languages; because Java, Node, Python, Ruby, etc. are all going to need upgrades while anything written in 'native' languages (RPG, COBOL, C/C++, CL) compiles right down to MI and will keep working forever without changes.

snuxoll··on User ban controversy reveals Bluesky’s decentralized aspiration isn’t reality
What are you talking about? Yes, it is closed - their PDS implementation and clients are open, but the actual service that runs on bsky.app is, at present, not open source.

Without the backend that handles all of the XRPC endpoints [1] being available, BlueSky still effectively maintains centralized control over their part of the 'atmosphere'. Somebody could, of course, make an open source implementation of the app.bsky lexicon and users would only need to update their DID to point at their preferred instance, but AFAIK none exists right now.

[1]: https://docs.bsky.app/docs/api/at-protocol-xrpc-api

snuxoll··on User ban controversy reveals Bluesky’s decentralized aspiration isn’t reality
I think there’s a lot of misconceptions about atproto; unlike ActivityPub where your home server runs both the application as well as stores your data, atproto is build in the concept that “applications” like BlueSky store your data inside your PDS (Personal Data Store), which may or may not be hosted somewhere else.

While anybody can host their own PDS, the public bsky.app instance can and will “block” users by preventing their login and not pulling data from the PDS of the banned user or showing it in feeds.

Since, to date, the BlueSky “AppView” (the service backend itself that handles aggregating data, generating feeds, etc.) continues to be closed, being banned from the public instance is effectively being banned from the network. The data model (lexicon) is well documented and somebody else is free to write their own, but, for now, BlueSky is just as centralized as other platforms even if you can store your data elsewhere.

snuxoll··on Adding OR logic forced us to confront why users preferred raw SQL
You just mentioned PostgreSQL, which, like pretty much every RDMBS sans MySQL, DB2/400, and maybe DB2/ZOS (never worked with the ZOS variant) supports schemas. If you need to worry about this, keep your tables that actually contain your data in one schema, then keep views, functions/stored procedures, etc. in separate schemas every time you make incompatible changes.

The database is a separate component, the biggest mistake nearly every developer makes is trying to make a single application own it. Let me tell you, from experience, the chances that this one single application will be the only thing that every connects to your database past initial development is slim. "Oh, but we're doing microservices and everything only ever talks over HTTP or gRPC" - yeah, sure, and I don't have a backlog of tech debt a mile long.

← PreviousPage 2 of 34Next →