frontpage.
newsnewestaskshowjobs

Made with ♥ by @iamnishanth

Open Source @Github

Ask HN: Economists, what's your opinion on US tariffs?

1•pinkmuffinere•2m ago•0 comments

Trakt: Upcoming VIP Renewal Pricing Changes – Effective May 20, 2025

https://forums.trakt.tv/t/upcoming-vip-renewal-pricing-changes-effective-may-20-2025/56649
1•27stkt6s•5m ago•0 comments

The Rise of Vibe Coding

https://www.haydenbleasel.com/blog/vibecoding
1•fmerian•5m ago•0 comments

Forgetting Is the Friend of Learning

https://deliramente.com.br/posts/Forgetting-is-the-friend-of-learning
1•Dnllira•5m ago•1 comments

Student Loan Delinquencies Are Back and Credit Scores Take a Tumble

https://libertystreeteconomics.newyorkfed.org/2025/05/student-loan-delinquencies-are-back-and-credit-scores-take-a-tumble/
2•jnord•6m ago•0 comments

US District Ct. for W. Pa. allows removal of Venezuelans under Alien Enemies Act [pdf]

https://storage.courtlistener.com/recap/gov.uscourts.pawd.318716/gov.uscourts.pawd.318716.72.0_4.pdf
2•treetalker•7m ago•1 comments

Type-Constrained Code Generation with Language Models

https://arxiv.org/abs/2504.09246
1•tough•8m ago•0 comments

Eliminating Array Bounds Checks

https://www.romainguy.dev/posts/2025/eliminating-array-bounds-checks/
1•mfiguiere•10m ago•0 comments

How (memory) safe is Zig?

https://www.scattered-thoughts.net/writing/how-safe-is-zig/
1•vortex_ape•11m ago•0 comments

Ask HN: Relational DB to Graph DB?

1•mysteriousBag•11m ago•0 comments

The Colorless Man (Short Film Made with a $600 Budget)

https://old.reddit.com/r/midjourney/comments/1kls7kl/the_colorless_man_short_film_made_with_a_600/
1•rubslopes•12m ago•0 comments

Preview release of ty, a type checker for Python

https://twitter.com/charliermarsh/status/1922333022658978089
1•jez•16m ago•0 comments

Show HN: Simple AI-powered commit msgs script

https://tomdekan.com/articles/ai-commit-messages
1•tomdekan•21m ago•0 comments

OpenAI Is in Talks to Acquire Programming Tool Windsurf for $3B

https://www.nytimes.com/2025/05/13/technology/openai-windsurf-talks.html
1•donohoe•25m ago•0 comments

Y Combinator says Google is a monopolist, no comment about its OpenAI ties

https://techcrunch.com/2025/05/13/y-combinator-says-google-is-a-monopolist-that-has-stunted-the-startup-ecosystem/
10•mastazi•25m ago•1 comments

Consultant Means Nothing (and Everything) – breaking down the mess of labels

https://davidraistrick.com/blog/2025-05-13-consultant-means-nothing/
1•keen99•29m ago•1 comments

The Vibes

https://taoofmac.com/space/blog/2025/05/13/2230
1•rcarmo•30m ago•0 comments

Florida Ban on "… Lewd Conduct" … Where Children Are Present Struck Down

https://reason.com/volokh/2025/05/13/florida-ban-on-depicting-or-simulating-lewd-conduct-in-performances-where-children-are-present-struck-down/
1•treetalker•30m ago•0 comments

The Penultimate Conditional Syntax

https://dotat.at/@/2025-05-13-if-is.html
1•todsacerdoti•30m ago•0 comments

Pete Rose among players reinstated by MLB commissioner Rob Manfred

https://www.cincinnati.com/story/sports/mlb/reds/2025/05/13/pete-rose-reinstated-mlb-commissioner-rob-manfred-eligible-baseball-hall-of-fame/83605873007/
1•gscott•31m ago•0 comments

AI Hallucination in Filings Involving … Law Firm Lead to $31K in Sanctions

https://reason.com/volokh/2025/05/13/ai-hallucination-in-filings-involving-14th-largest-u-s-law-firm-lead-to-31k-in-sanctions/
1•treetalker•32m ago•0 comments

Cardiac: A CARDboard Illustrative Aid to Computation [pdf]

https://www.cs.drexel.edu/~bls96/museum/CARDIAC_manual.pdf
4•throwaway71271•34m ago•0 comments

Y Combinator's Little Tech Summit was a bizarre snapshot of DC

https://www.theverge.com/politics/651439/maga-tech-populism-antitrust-bannon-lina-khan-ftc
2•baobun•34m ago•0 comments

Insurers seek to surcharge California homeowners for L.A. County fire costs

https://www.latimes.com/business/story/2025-05-13/insurers-seeking-to-surcharge-california-homeowners-for-l-a-county-fire-costs
1•speckx•34m ago•0 comments

Research: Gen AI Makes People More Productive–and Less Motivated

https://hbr.org/2025/05/research-gen-ai-makes-people-more-productive-and-less-motivated?ab=HP-hero-featured-1
1•pseudolus•35m ago•0 comments

FreeBSD fans rally round zVault upstart

https://www.theregister.com/2025/05/12/second_preview_zvault/
1•rodrigo975•36m ago•0 comments

Matrix3D: Large Photogrammetry Model All-in-One

https://nju-3dv.github.io/projects/matrix3d/
2•bentocorp•42m ago•0 comments

Gravity Could Be Proof We're Living in a Computer Simulation

https://gizmodo.com/gravity-could-be-proof-were-living-in-a-computer-simulation-new-theory-suggests-2000601707
2•jchrisa•43m ago•0 comments

Amazon warns it'll terminate your account for screenshotting Prime Video

https://www.neowin.net/news/amazon-allegedly-warns-itll-terminate-your-account-for-screenshotting-prime-video/
6•bundie•45m ago•2 comments

Adwaita Sans and Mono Typefaces

https://gitlab.gnome.org/GNOME/adwaita-fonts
1•cl3misch•46m ago•0 comments
Open in hackernews

Don't unwrap options: There are better ways (2024)

https://corrode.dev/blog/rust-option-handling-best-practices/
73•mu0n•4h ago

Comments

ChadNauseam•3h ago
let-else is awesome. definitely my favorite rust syntax. The compiler checks that the else branch will “diverge” (return, panic, break, or continue), so it’s impossible to mess it up.

the article says “It’s part of the standard library,” which gets the point across that it doesn’t require any external dependencies but it may be slightly misleading to those who interpret it literally - let-else a language feature, not part of the standard library, the relevant difference being that it still works in contexts that don’t have access to the standard library.

I tend to use Option::ok_or more often because it works well in long call chains. let-else is a statement, so you can’t easily insert it in the middle of my_value().do_stuff().my_field.etc(). However, Option::ok_or has the annoying issue of being slightly less efficient than let-else if you do a function call in the “or” (e.g. if you call format! to format the error message). I believe there’s a clippy lint for this, although I could be mixing it up with the lint for Option::expect (which iirc tells you to do unwrap_or_else in some cases)

I appreciate the author for writing a post explaining the “basics” of rust. I’ll include it in any training materials I give to new rust developers where I work. Too often, there’s a gap in introductory material because the vast majority of users of a programming language are not at an introductory level. e.g. in haskell, there might literally be more explanations of GADTs on the internet than there are of typeclasses

progbits•3h ago
> I believe there’s a clippy lint for this, although I could be mixing it up with the lint for Option::expect (which iirc tells you to do unwrap_or_else in some cases)

It's one lint rule which covers bunch of these _or_else functions: https://rust-lang.github.io/rust-clippy/master/#or_fun_call

frizlab•2h ago
Swift has guard. Equally awesome.
cibyr•3h ago
Anyhow warrants more than an honorable mention, IMO. anyhow::Context is great, and basically always an improvement over unwrap() - whatever complaints you might have about anyhow::Error, it's infinitely easier to handle than a panic.
Ar-Curunir•3h ago
Really useful article to learn about idiomatic Rust :)

In general I think there is a lack of intermediate Rust material that teaches you common design patterns, idiomatic Rust, and so on.

Even I (someone who's written hundreds of thousands of fairly complex Rust code) learnt about the let-else style solution from this article =).

Zambyte•3h ago
I have been using Zig a lot lately, and I just want to share the equivalent of the let-else solution in Zig:

   const user = getUser() orelse return error.NoUser;
If you only need user for a narrow scope like you would get from match, you can also use if to unwrap the optional.

    if (getUser()) |user| {
        // use user
    } else {
        return error.NoUser;
    }
robertlagrant•3h ago
And the same in Python:

  if user := get_user() is not None:
    # use user
  else:
    # return error
Although given the happy path code can mean you don't see the error condition for ages, I much prefer this:

  if (user := get_user()) is None:
    # return error

  # use user
aatd86•2h ago
hehehe. reminds me of if err != nil in Go which is really not an issue in my opinion. But it seems to have become somewhat infamous in some circles.
jimbokun•2h ago
The problem is the compiler doesn’t help you if you forget to check err.

Although it will flag unused variable. So you will have to make an effort to deliberately ignore the error value.

Still not quite as nice as the compiler forcing you to handle the error case.

int_19h•1h ago
The problem is that idiomatic Go reuses err for multiple calls. So if you already have one call and check err after, it counts as used, and forgetting to check it on subsequent calls is not flagged.
LtWorf•2h ago
It is a massive problem. It's basically the worse thing about C and they decided to copy it.

Easily 60-70% of all go code is about propagating errors to the caller directly.

fjasdfas•2h ago
`:=` was new to me: https://peps.python.org/pep-0572/

It actually looks really natural in python, glad they added.

fjasdfas•2h ago
gleam:

    fn get_user_name() -> Result(String, String) {
        use user <- result.map(option.to_result(get_user(), "No user"))
        user
    }
evrimoztamur•3h ago
Talking about unwrapping: I’ve been using a rather aggressive list of clippy lints to prevent myself from getting panics, which are particularly deadly in real-time applications (like video games). unwrap/expect_used already got me 90% of the way out, but looking at the number of as conversions in my codebase, I think I have around 300+ numerical conversions (which can and do fail!)

    [lints.clippy]
    all = "deny"
    unwrap_used = "deny"
    expect_used = "deny"
    panic = "deny"
    indexing_slicing = "deny"
    unhandled_errors = "deny"
    unreachable = "deny"
    undocumented_unsafe_blocks = "deny"
    unwrap_in_result = "deny"
    ok_expect = "deny"
an_ko•3h ago
Does that mean your code is annotated with 300+ instances of `#[allow(clippy::unwrap_used)]` et al?
evrimoztamur•2h ago
It was the first time I set it up, then I went through every single instance and refactored with the appropriate choice. It wasn't as tedious as you might imagine, and again, I really don't have the option of letting my game crash.

I think the only legitimate uses are for direct indexing for tile maps etc. where I do bounds checking on two axes and know that it will map correctly. to the underlying memory (but that's `clippy::indexing_slicing`, I have 0 `clippy::unwrap_used` in my codebase now).

If you begin a new project with these lints, you'll quickly train to write idiomatic Option/Result handling code by default.

p1necone•2h ago
yoink (although I will probably allow expect - having to provide a specific message means I'm only going to use it in cases where there's some reasonable justification)
mplanchard•1h ago
This is nice, but fairly miserable to deal with in in-module unit tests, IMO.

We get around it by using conditional compilation and putting the lints in our entrypoints (`main.rs` or `lib.rs`), which is done automatically for any new entrypoint in the codebase via a Make target and some awk magic.

As an example, the following forbids print and dbg statements in release builds (all output should go through logging), allows it with a warning in debug builds, and allows it unconditionally in tests:

    #![cfg_attr(not(debug_assertions), deny(clippy::dbg_macro))]
    #![cfg_attr(not(debug_assertions), deny(clippy::print_stdout))]
    #![cfg_attr(not(debug_assertions), deny(clippy::print_stderr))]
    #![cfg_attr(debug_assertions, warn(clippy::dbg_macro))]
    #![cfg_attr(debug_assertions, warn(clippy::print_stdout))]
    #![cfg_attr(debug_assertions, warn(clippy::print_stderr))]
    #![cfg_attr(test, allow(clippy::dbg_macro))]
    #![cfg_attr(test, allow(clippy::print_stdout))]
    #![cfg_attr(test, allow(clippy::print_stderr))]
AFAIK there isn't currently a way to configure per-profile lints in the top-level Cargo configs. I wish there were.
sophacles•3h ago
> My main gripe with this error message is that it doesn’t explain why the ? operator doesn’t work with Option in that case… just that it doesn’t.

The error in question:

> the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result`

It literally tells you why it doesn't work, wtf do you want?

eviks•2h ago
Indeed, and it even suggests the 2nd solution. All you have to do is read from the top, not the bottom, of the error message
the__alchemist•3h ago
Something I use for situations where nesting is getting out of hand. Probably not idiomatic but, I find it practical in these cases.

  if param.is_none() {
    // Handle, and continue, return an error etc
  }
  let value = param.as_ref().unwrap(); // or as_mut
  // Use `value` as normal.
acjohnson55•2h ago
Any advantages of this over let-else?
the__alchemist•1h ago
I wasn't familiar with let-else...
rav•2h ago
You can rewrite it using let-or-else to get rid of the unwrap, which some would find to be more idiomatic.

    let value = Some(param.as_ref()) else {
      // Handle, and continue, return an error etc
    }
    // Use `value` as normal.
the__alchemist•1h ago
That part intrigued me about the article: I hadn't heard of that syntax! Will try.
epidemian•1h ago
Small nit: the Some() pattern should go on the left side of the assignment:

    let Some(value) = param.as_ref() else {
      // Handle, and continue, return an error etc
    }
    // Use `value` as normal.
vmg12•3h ago
Also, sometimes just unwrap it. There is some software where it's perfectly fine to panic. If there is no sane default value and there is nothing you can do to recover from the error, just unwrap.

Also, sometimes you just write software where you know the invariant is enforced so a type is never None, you can unwrap there too.

I find it interesting how a lot of people find Rust annoying because idiomatic Rust is a very strict language. You still get a ton of the benefits of Rust when writing non-idiomatic Rust. Just use the Rc<RefCell<>> and Arc<Mutex> and feel free to unwrap everything, nobody will punish you.

0cf8612b2e1e•3h ago
Plus it gives others the opportunity to post that xkcd velociraptor strip.
iyn•2h ago
https://xkcd.com/87/ this one?
Hackbraten•2h ago
Do you mean this one? https://xkcd.com/292/
0cf8612b2e1e•2h ago
Yes, exactly. It is the Rust equivalent of goto.
vmg12•2h ago
Goto is bad because it results in very difficult to reason about code. Using unwrap and expect is as bad as using any other language without null safety.
int_19h•1h ago
goto is bad when it's used in a way that makes it difficult to reason about code, but not all uses of goto are like that. The usual C pattern of `if (err) goto cleanup_resources_and_return_err;` is a good example of the use of goto that is not difficult to reason about.

Using unwrap/expect is still much better than using a language without null safety because unwrap/expect make it immediately obvious at which point a panic can occur, and creates some friction for the dev writing the code that makes them less likely to use it literally everywhere.

p1necone•2h ago
Imo always expect rather than unwrap in those cases. If it's justifiable, you should justify it in the message.

("This should never happen because: ..., if you see this message there's a bug.")

Arnavion•2h ago
Or let-else with a panic!() in the else {} if you want to use a format string.
tengbretson•2h ago
I'm not very familiar with Rust. Do the built in Option and Result types not implement map and flatMap?
trealira•2h ago
They do implement both of those, except instead of flat_map, it's called and_then for Option and Result.
theon144•2h ago
They do, `map` and `and_then`.

As for the article, I'm also a bit confused because I'm really not sure whether people write that sort of code at the beginning "very commonly" - match and `ok_or` to handle None by turning them into proper Errors is one of the first things you learn in Rust.

Sharlin•2h ago
As others have said, you can `and_then` chain `Options`, but often it’s better to convert each `Option` into a `Result`s before chaining, to get more fine-grained error messages as shown in the fine article. But usually it’s cleaner and more convenient (and friendlier to people used to exceptions) to use the `?` operator which is basically Rust’s `do` notation except that currently you can only early-return from the entire function with it, not escape a specific block. Which in turn requires the types to match, though Rust does at least insert an `.into()` conversion for the error value.
rienbdj•1h ago
How long till the Rust community starts to push do notation and monad transformers?
keybored•39s ago
Eight years ago?
Sharlin•1h ago
> I find the name ok_or unintuitive and needed to look it up many times. That’s because Ok is commonly associated with the Result type, not Option.

Hmm, I kind of disagree. The method literally returns “OK or an error”. It converts an Option into a Result and the name reflects that.

There is something of an inconsistency though, although IMHO it’s worth it. The `Result::ok()` method returns a Some if it’s Ok, and None otherwise, which is concise and intuitive but indeed different from `Option::ok_or`.

tekacs•1h ago
I use a setup like this:

https://gist.github.com/tekacs/60b10000d314f9923d6b6a5af8c35...

where... in my code, I have:

  some_block({ ... }).infallible()
for cases where we believe that the Result truly should never fail (for example a transaction block that passes through the inner Result value and there is no Result value in the block) and if it does then we've drastically misunderstood things.

Then, there's an enum (at the bottom of the file) of different reasons that we believe that this should never fail, like:

  // e.g. we're in a service that writes to disk... and we can't write to disk
  some_operation.invariant(Reason::ExternalIssue)
  // we're not broken, the system wasn't set up correctly, e.g. a missing env var
  some_operation.invariant(Reason::DevOps)
  // this lock was poisoned... there's nothing useful that we can do _here_
  some_operation.invariant(Reason::Lock)
  // something in this function already checked this
  some_operation.invariant(Reason::ControlFlow)
  // u64 overflow of something that we increment once a second... which millennium are we in?
  some_operation.invariant(Reason::SuperRare)
... etc. (there are more Reason values in the gist)

This is all made available on both Result and Option.

mcflubbins•34m ago
I with there was a clippy check for unwrap(), I have very very rarely needed it in practice.