HNHacker News
TopNewBestAskShowJobs

ragnese

2,531 karma · joined December 14, 2017

submissionscomments
ragnese··on Introducing a terms of use and updated privacy notice for Firefox
Do hammer manufacturers required you to sign an agreement at the hardware store with a bunch of legalese so they aren't held liable if you use the hammer to beat someone to death?

Do alcohol companies get shut down when people drink and kill someone with their car?

Did you know that a nonzero percentage of child molesters wear Nike sneakers when they kidnap children? Why doesn't Nike actively try to prevent this?!

So why should a VPN provider need to explicitly dissuade its customers from breaking the law with their service? Why should a web browser be afraid of being on the hook when someone breaks the law via the web?

ragnese··on Signal to leave Sweden if backdoor law passes
All of them?
ragnese··on AI is stifling new tech adoption?
> I know nothing about pathology, but in terms of software, I think slower adoption to new tech is what we need, especially when the "new tech" is just a 5% faster javascript framework.

I hope that's not the definition people are using when discussing adoption of "new tech".

When it comes to the topic of AI and "new tech adoption", I think about something like the Rust programming language.

I apologize if it chafes the people reading this comment that I'm something of a Rust evangelist and I'm working from a point of view that Rust's very existence is a (large) net-positive when it comes to programming and how we think about programming language design.

My fear with AI tools in their current state is that it will slow down innovation in programming languages. Rust gained popularity because it brought things to the table that made writing safe, performant, and correct (thinking about the strong, expressive, static type checking) software much easier than it had been with the old incumbents (in certain domains).

But, if Rust were released today or in the near future, would it take off? If we could, hypothetically, get to a point where an AI tool could spit out C or C++ code and push it through some memory sanitzers, Valgrind, etc and just iterate with itself until it was very likely to be free of memory safety bugs, why would we need a new language to fix those things? I guess we wouldn't. And it wouldn't really matter if the code that gets generated is totally inscrutable. But, it saddens me to think that we might be nearing the end of human-readable programming language research and design.

ragnese··on Mullvad has partnered with Obscura VPN
I've not heard/read this before, but I use Mullvad and my anecdotal experience confirms this. I get blocked or put into a captcha trap quite frequently. I assumed this would be an issue for any/all well-known VPN IPs. Are you saying that it's not? Do you have any alternative recommendations?
ragnese··on Ask HN: What intelligent forums exist outside of HN?
Yikes. Replying because I noticed my egregious typo: "theirs", not "there's".
ragnese··on Ask HN: What intelligent forums exist outside of HN?
That can certainly be true, too. But different people will have different thresholds for how much enshitification is too much. So, you hit your threshold in 2020 and OP hit there's today.
ragnese··on Trump says he has directed Treasury to stop minting new pennies
I have a similar question. I always heard/read that the whole "pennies cost more to make than they're worth" argument was a red herring, in that it doesn't really matter how much they cost to make "at rest". But, rather, the value of a penny is in how much wealth it allows to be transferred over its life in circulation. In other words, if a penny does cost about 3.69 cents (or whatever they say the number is today) to mint, then it is "worth it" as long as the penny is used 4 times EVER.

I'll admit that I really haven't given much thought to the topic in any case. But, even in just the time it's taking me to write this comment, I'm realizing it's probably a little of both "sides" being right. After all, a penny is both a medium of exchange as well as a store of wealth/value, depending on how you use it...

ragnese··on Ross Ulbricht granted a full pardon
Interesting observation. I agree and upvoted. ;)

EDIT: I'm not being sarcastic, either, BTW. But, I do love the irony of writing a positive reply to your comment.

ragnese··on Ozempic and Wegovy are selected for Medicare's price negotiations
I mean, it's certainly settled for me. At the same time, I think it would dishonest to insinuate that there are NOT people claiming the Earth is flat on the internet (Honestly, I don't believe that flat-earthers actually believe that--I think they're all trolling).

So, I don't know. I guess I just wanted to chime in to note that I have seen people repeat this crap about calories.

ragnese··on Ozempic and Wegovy are selected for Medicare's price negotiations
Quite true!
ragnese··on Ozempic and Wegovy are selected for Medicare's price negotiations
> The debate has never been "will consuming less calories than you expend make you lose weight"

Maybe the debate amongst actual doctors and researchers. But, the debate amongst dummies on the internet (social media) CERTAINLY had people arguing that it was somehow about more than the number of calories in and out.

ragnese··on Supreme Court rules to uphold TikTok ban, setting stage for shutdown
We also risk losing so much utter nonsense and false information that I'm not at all worried. You want to learn history and science? Buy some (vetted) history and science books.

The number of times I had to correct my step-son when he repeated something he "learned" on TikTok is disturbing.

Unimportant example: He "learned" from a TikTok video that the commonly repeated command of "Open sesame!" is actually "Open says me!". That's not true, and all you have to do is read the story "Ali Baba and the Forty Thieves" to know that the story actually hinges on the fact that the secret word is the name of a grain/plant.

Another example: He "learned" that the video game character, Mario, is not saying "It's a me, Mario!" with an Italian accent. He "learned" that he is actually saying some Japanese word, like "Itsumi Mario!".

One more: He "learned" that "scientists" now think that "we" originally put the T-Rex fossils together incorrectly and that the animal's arm bones are actually backwards, and should be reversed to reveal that the T-Rex actually had little chicken wings instead of small arms. Anybody who has seen how bone sockets fit together knows that's nonsense.

Forgetting the political theory and morality of the ban, I say good riddance to the constant firehose of bullshit and lying morons on that app.

ragnese··on I Switched to Firefox and Never Looked Back
I was convinced at the time--and I'm still convinced--that there was a TON of astroturfing on places like Reddit and even here when Nadella became CEO of Microsoft and there was that whole "Microsoft hearts Open Source" campaign. Every other comment was "You're just stuck in the past. You're as bad as the conspiracy theorists. It's not even the same people running the company anymore. Blah blah blah."

And now they own Github and they're training their AI models on you and your code and forcing that crap into a bunch of PCs. They were about to push out a "feature" to Windows that periodically took screenshots of what you were doing and used AI to analyze what you were doing. Then they sprinkle some glitter for the easily-distracted and tell you that it's actually a feature for you. Last I heard, they shelved the idea for now because of the backlash, but we all know they'll circle back around.

But, yeah, I'm a tinfoil hat weirdo who's just a "hater."

ragnese··on Right to root access
Exactly. Even the people who complain about these things immediately get defensive when you call them out on their uses: "Well, I can't switch because what about my banking app?" or "Well, games don't count as software to me." or "It won't make any difference to the big tech companies if I'm the only one who switches, so why bother?"
ragnese··on Error Stacking in Rust
It's fun to think through examples like this. But, of course, we need to exercise caution because so much is dependent on the specific contexts of each individual project.

First, I will say that I probably misspoke (mistyped...?) by using the word "unrecoverable". At the end of the day, it's not even really about whether or not something is recoverable, but it's really just about whether the caller might "want" to be aware of it and how much detail the caller needs.

For your example, you end up writing,

> It's also highly limiting because the caller now can't distinugish between programmer errors and possibly-transient environmental conditions like a service outage.

That's the giveaway that the caller needs to know about service outages, specifically. So, you need to handle your HTTP requests and/or database queries in such a way that you can incorporate some of the failures into your function's error type.

But, you SHOULD NOT just implement `From` for converting all of your database library's errors into your function's error type. You have to actually inspect the error returned from the database and return an appropriate error. Specifically, if you're using a SQL db library, it might return an error if your query generating invalid SQL statements--that should be a panic because that's not a "service outage", that's a programmer bug in the implementation of the function. Likewise, an auth error is not the same as an outage. If the db library specifically returns an error that it can't make a connection, then that's the one you'd want to wrap in your error type in this example.

But, again, it all depends on exactly what kind of project we're working on. Your example of doing HTTP, and filesystem, and database queries reminds me of Firefox. Firefox obviously does HTTP stuff, and it uses the filesystem and a SQLite database for settings or configs or something... So, if we were talking about your example function in the context of writing a web browser, then a failed HTTP request is 100% normal and expected because the user's device might connect and disconnect from the internet at any time. So, HTTP failures should be represented in the function's signature. However, since the SQLite database is basically part of the application, itself, any errors when trying to query it are probably panic-worthy. Phrased differently: it's a working assumption of the application that the database is always accessible, so there's no reason to describe failure modes that aren't supposed to ever happen. If the database ever became inaccessible, the top-level main function should catch all panics, log something about them (maybe send off telemetry data, etc), and warn the user that an unexpected error occurred and either tell them to restart the app or just kill ourselves, etc.

Have you ever written a function that returned a `String`? Or a `Vec`? Well, those require memory allocations and they may fail and panic. But, I've never worked in a context where it made sense to try to catch those panics and change those function signatures into `Result<String, OOM>`. My applications choose to assume that enough memory will be available, and I've made the decision to allow the apps to crash and burn if that assumption ends up violated rather than add the large burden of carefully handling that possibility in every line of code in these projects. And, so far, that has been the right call because none of my Rust projects have ever OOM'd yet (and some have literally been running in production for multiple years), and there's really nothing I would want to specifically do if they did-- I'd either figure out how to reduce the memory requirements or increase the server's memory.

ragnese··on Error Stacking in Rust
You definitely won't find me defending Java too often. And I certainly agree that there are frustrating limitations. Like you said, it's annoying that Java does have ad-hoc union types, but only for the throws list in function signatures and for the type specification in catch blocks. So, it's definitely painful that you can't use a similar syntax when implementing something like the generic interface example I wrote.

> You also can't make a `class MyException<T>`. Or do a `catch (T e)`. There are a lot of blockages in practice to trying to do any of this - exceptions are very special in the type system, which is the problem.

Agreed.

But, my entire contention with the discussion around checked exceptions is that everyone found some sharp edges and limitations with Java's checked exceptions and instead of deciding that Java suck{ed,s}, everyone seemed to decide that checked exceptions suck. That was the wrong conclusion, IMO, and I truly believe it has slowed progress in programming language design.

It's only recently that statically typed failure modes are becoming mainstream again (e.g., Rust, Swift, and many third-party libraries for languages like TypeScript and Kotlin among others).

Speaking of streams and combinators like map, Swift has the `rethrows` keyword which is absolutely awesome, IMO. It's this kind of progress that I think we've missed out on from everyone rejecting checked exceptions as a concept for the last decade or so. We threw the baby out with the bathwater.

ragnese··on Error Stacking in Rust
But, this isn't you complaining about checked exceptions vs Result. This is you complaining about Java's overall syntax style vs Rust's.

Phrased another way, Java's syntax is fairly verbose for everything, not just for try-catching to handle exceptions.

ragnese··on Error Stacking in Rust
I generally disagree with you. I think that Result/Try types are essentially isomorphic to checked exceptions.

> Java's checked exceptions are the worst. Having to declare every exception thrown as a part of your API/ABI makes for brittle, difficult-to-evolve interfaces.

How is this different, in practice, from how it's done in Rust? You have to evolve your Result error type as well. The exact same concerns exist for both. The difference is that you actually have more choice/freedom with Java: you can choose to wrap all of your API's checked exceptions under one base type (analogous to defining a single error type for Result in Rust) so your function throws a single exception type, or you can have your function signature use an ad-hoc union type of several exception types without the boilerplate of wrapping them in a new type. In fact, many people have requested ad-hoc union types in Rust for a long time, because it's so painful to choose between all of your functions returning the same umbrella error type even though it only truly needs a subset of it vs. defining new mostly-redundant error types for each function in your API.

> Rust's Result and '?' syntax sidesteps a few of these issues. You can "add" underlying errors to the error return of your function without changing its API/ABI. You don't need to add a bunch of try/catch blocks, cluttering and confusing the code, in order to make sense of this and convert exceptions into whatever your API/ABI specifies. Rust's 'From<>' trait is damn-near magical when it comes to error conversion and propagation.

As I mentioned above, you can certainly define a base exception type (and you probably should in many cases) in Java, too. Yes, Java's syntax is fairly verbose, but Java's syntax is verbose for almost all of the language. So, is it the checked exception mechanism that is "bad", or is it just that all of Java is verbose? My take is that checked exceptions are, overall, good, and the syntax to work with them in Java is similarly tedious as the rest of the language.

Also, as a tangent, I kind of hate `From<>` in Rust. I think people lean on it way too much. It certainly makes the code shorter and "cleaner", but it also makes it harder to understand because of how implicit it is. And it causes people to miss opportunities where they actually could or should handle an error, just because the types happen to line up so that you can use `?`, instead of thinking about the actual local logic.

> I get that not everyone is a functional programming enthusiast, but you can't do FP with exceptions. (Well, you can, via a sort of Try monad like Scala has, but it's error-prone and ugly to deal with.) With Result, you can, and it works seamlessly with the rest of the language and syntax.

Can you elaborate on this? I feel like Scala's Try and Either are almost exactly the same as Rust's Result.

ragnese··on Error Stacking in Rust
You can have generic `throws` markers; e.g.,

    interface Frobinicator<E extends Exception> {
        void frobinicate() throws E;
    }
ragnese··on Error Stacking in Rust
Yeah, fair point about dtrace, et al, but I think my statement is still fine in context, since we're specifically talking about these Rust libraries that collect stack traces for error types.

And I agree and love having statically checked failure modes! So, if you're choosing to panic in Rust, it better be because of something that is really not able to be handled at all (caveat: the top-level event loop or whatever could catch panics/exceptions, print a "Oops! Something went wrong!" message to the user and then either die or try to keep going, etc, but no handling panics/exceptions in "middle" layers.).

ragnese··on Error Stacking in Rust
Yeah, that whole statement there is probably unnecessary and I can see it being off-putting. I'll edit it if I still can.

However, I just want to make it clear that I wasn't intending to call anyone a "bad programmer". At least not in a personally insulting way. We've all been in a position where we were uninitiated at something. And most of us have been in a situation where we've jumped into a new programming language without having any kind of "formal" education on the design, philosophy, and intended best practices. For example, with Java, one should read documents like: https://docs.oracle.com/javase/tutorial/essential/exceptions..., especially this part: https://docs.oracle.com/javase/tutorial/essential/exceptions....

So, again, that part wasn't actually meant as an insult. We're all uneducated about many things at every point in our lives. And I think that lack of education or guidance on designing error types and handling has caused a lot of people to end up burying themselves in checked exception hell, and dismissing the whole thing because of that frustration.

The other part about cargo-culting... well, yeah, that was me insulting people.

ragnese··on Error Stacking in Rust
You're not far off. This is one of my favorite topics in programming language design discussions, and I have opinions that some may even say are "controversial". For what it's worth, I've been writing Rust in production since 2016 (not 100% of my time since then, but I've had a good amount of experience with some decently long-lived projects of varying complexity).

First, I assert that Java's checked exceptions are a solidly good feature. Of course it has flaws. The whole rest of the language is also full of flaws, so that's not surprising.

Second, I assert that there are two things that have caused the vast majority of hate toward Java's checked exceptions: programmers not being taught/shown how and when they're intended to be used, and that oft-circulated interview transcript from 2003 where Anders Hejlsberg asserts that checked exceptions are language design "dead end". I don't think he was right in 2003, and I especially don't think the opinion is correct today in light of how much strong static typing has really gained favor with the programming community. But, that opinion really took off and we spent years and years seeing that assessment repeated as a truism, which I think is why it took so long to finally start experimenting with statically typed failure modes again (e.g., Rust and Swift).

Now, here's where I'll get controversial about Rust error handling. I'll try really hard to keep this from turning into an entire dissertation, but I'll elaborate if anyone asks.

It is often a mistake to implement the `From` trait for error types and use the `?` operator everywhere. Error types in an API need to be aware of the context in which they occur, so just converting by type only often doesn't make sense. You may encounter a `FooError` type while your app is doing totally different things, so it's likely that not every `FooError` occurrence means the same thing to whoever is calling into your code. Also, sometimes you can actually handle an error, and getting into the muscle memory habit of just tacking `?` on to everything can lead to mistakenly propagating errors that you might have better handled by doing something else (including perhaps panicking).

There does seem to be a trend toward automatically adding stack traces in Rust errors. This is completely misguided, IMO. And this may be my MOST controversial opinion: stack traces almost *never* belong in a `Result<>` error type. Result types should be relevant to your "domain" (borrowing the term from "Domain Driven Design" even though I do NOT advocate for DDD in general).

Think about it this way: designing an API is about abstraction. So if you write a integer division function that takes two arguments and divides them, it might return `Result<i64, DivideByZero>`. If the caller passes in a 0 divisor, then what business is it of theirs to see what your private functions are called, how many of them are called, and what line of your file they were defined on? That's the leakiest of leaky abstractions.

You might be thinking: "But, if I see an result/error value that I didn't expect while running my program, the stack trace will help me track down the issue!" Yeah, no kidding. So, let's also start adding stack traces to our successful values, too! After, all, if I call my division function and get back a `Result::Ok` with a weird number that I didn't expect, I might want to trace that back, too, right? (This suggestion is sarcastic to prove a point. It should, hopefully, sound ridiculous to add stack traces to every return value from every function.)

The issue is that Rust's Result (and Java's checked exceptions) require a different paradigm. A Result is in the type signature because it's part of your domain's API design. It's just values. It's not *for* debugging. You use a debugger for that or programmatically panic when something is truly unexpected and get the stack trace from that.

Which leads to the corollary to the previous controversial opinion: Rust has unchecked exceptions; they're called panics and they are 100% *okay to use* in the vast majority of applications that the vast majority of day-job programmers work on.

Obviously, context matters, and there are some places where panicking is unacceptable. But, Result is for expected domain failures. Panics are for programmer errors and unrecoverable constraint violations. And I'm not advocating for panics to be "lazy". Rust code that refuses to ever panic (as far as they know, but I hope they aren't indexing any vecs/arrays just in case!) usually leads to overly polluted error types where it ends up being difficult to understand what errors are actually meaningful and what errors are never actually going to happen. Instead of inspecting errors and figuring out which to handle and how, I've seen things just snowball into a giant mess of nested enums with sometimes redundant error "branches" and missed opportunities to actually handle some cases. If you, as the programmer, know for sure that you just added something to a HashMap earlier in your function and you know you didn't remove it, then for the love of all things sacred, just write `map.get("my-key").unwrap()` (or `.expect("message")`--whatever) instead of making the caller have to consider an error that will never happen, is not their fault, and that they can't do anything about!

And, if you do have a situation where panicking is unacceptable (you must be using `#![no_std]`, right??), then don't make a bunch of different error types for all of the possible programmer bugs. Just make a single umbrella `FatalError` type and use that.

For further reading, I really like this piece from the book Real World OCaml, which also has a Result type and exceptions: https://dev.realworldocaml.org/error-handling.html. Specifically, the very last section at the bottom of the page, titled: "Choosing an Error-Handling Strategy". (The old version of that page used to be more plain HTML and the sections had anchors so I could link directly to that section...)

And for further reading about error handling strategy in a no-panic context, I really like the approach described here: https://sled.rs/errors

ragnese··on Why America's economy is soaring ahead of its rivals
I find it pretty egregious that someone who is saving/investing a chunk of every paycheck could be considered to be "living paycheck-to-paycheck." I feel like the most obvious definition most of us would assume is that nearly 100% of your paycheck gets spent on goods and services, and/or bills and debts, before your next paycheck.
ragnese··on Malware can turn off webcam LED and record video, demonstrated on ThinkPad X230
Oh, bummer. I definitely had assumed that they were a single "device".
ragnese··on Malware can turn off webcam LED and record video, demonstrated on ThinkPad X230
Eh. If it's not a physical power-disconnect switch, one could imagine it still being able to record audio, which still sucks.
ragnese··on Analysis of economic and productivity losses caused by cookie banners in Europe
Oh, it's definitely malicious compliance. I have no doubt.
ragnese··on Trump wins presidency for second time
You've been sharing this exact narrative all over the thread, which makes me think that you aren't really replying to my comment so much as you're just finding any pretense to share this same opinion again.

> The sentiment is Republicans are focused on winning while Democrats are focused on a deeply unpopular corporate-imperialist political project and scolding people into voting for them.

In the U.S. we are, for all practical purposes, stuck with two choices. Some people will vote for one side, while some people with vote against the other side. But, here you're claiming that people are voting for Republicans because they like them and people are voting for Democrats because they are being "scolded" into it. That is just you superimposing your opinion/analysis on to things. The only objective measure is that, until this election, Democrats consistently got more votes than Republicans. Period. You can read whatever tarot cards and tea leaves you want to figure out why.

> They will occasionally virtue signal elsewhere but their policies only align with the project > > Progressive policies on minimum wage, labor and other things won in Red States once again. Nebraska's minimum wage increase, for instance, went 75-25. 60% for Trump, 75% for minimum wage increase. > > It's important to realize the Democrats have no interest in those. Absolutely zero.

Let's get this straight. Voters in states that are being run by Republicans feel the need to take things into their own hands by going around their elected officials to implement progressive policies, like higher minimum wages. Voters in states that are being run by Democrats have NOT felt the need to add minimum wage increases to their constitutions.

And your conclusion from these facts is that it's the Democrats that don't care about increasing the minimum wage? Are you kidding? I think there's a MUCH more obvious interpretation here, and it's NOT that the Republican party is somehow in a more popular position when it comes to progressive policies...

ragnese··on Trump wins presidency for second time
1. I didn't say it was impressive. Just refuting the claim that the Republican party puts forth candidates that the electorate wants while the Democratic party does not.

2. Nobody has beaten Trump since he's been a convicted criminal, lied about winning an election he didn't, or stole classified documents from the White House. So it doesn't make sense to discuss "barely beating an incompetent [...]" in the context of my comment that refers only to Democratic candidates who ran before those things happened.

ragnese··on Trump wins presidency for second time
Both Hilary Clinton and Joe Biden got more votes than Donald Trump. The Democrats have a better track record of picking the more popular candidate that the electorate wants in recent history.

In fact, the Democratic candidate has won the popular vote in all four of the most recent elections before this one (from 2008 - 2020, inclusive).

ragnese··on Universe would die before monkey with keyboard writes Shakespeare, study finds
> Yes, but the theorem is meant to explain what can happen in the universe over long time scales.

I never understood it that way. I always interpreted it as a fun way to explain the mathematical truth that no matter how low a probability is, as long as it is technically above 0, the event it describes WILL eventually occur given enough time/trials/etc.

I can't see anybody ever interpreting it as a statement about the real, actual, universe. Just like I don't think anybody truly believes that flipping a real coin with non-identical sides (such as every currency coin I've ever used) must have EXACTLY 50% probability of landing on either side. Surely people can separate the mathematical ideal/concept from constraints of physical reality.

← PreviousPage 3 of 31Next →