HNHacker News
TopNewBestAskShowJobs

theamk

9,664 karma · joined May 4, 2016

submissionscomments
theamk··on Transit rewards
Probably because of UX?

At least in the US, the traditional taxis were terrible - only way to order is via phone call, you have no idea when your car will arrive, nor how much your trip will cost, there is no easy way to send feedback to driver, and there was a good chance for an generally unpleasant experience...

Uber/Lyft changed this all and actually made the car-for-hire services usable. In my circles, this was the real reason why everyone simply stopped using taxis completely the moment any alternatives appeared.

And Waymo has a nice app and clean experience, and won't take you long way so it can charge you more, hence people group it with rideshares, despite it technically being closer to taxi.

(I understand that in other countries, taxis were much better. Before Lyft, I always felt envious while reading about their taxi systems)

theamk··on Transit rewards
American busses are infrequent and often don't follow the schedule. This means any trip where you have to be at certain time (work meeting? class? personal meeting? some event? etc...), you have to add 30-60 minutes buffer, and that's on top of bus being already slower than the car.
theamk··on The Agent Economy Has No Auditor
> A bad employee loses money until a manager notices. A bad agent loses money at machine speed, around the clock, on every channel at once, and files a beautiful report about it.

> When banks are asked to finance businesses that are run in part by agents, what proof will they accept? A dashboard? A screenshot? A performance report written by the same agent that spent the money? No underwriter on earth should accept that. Eventually none will.

Good, that's exactly what we need. People believe Big AI companies way too much. We need loud, widely-published stories of AI agents making horrible decisions and wrapping them in beautifully-formatted reports, so that a layman working with AI knows it will lie with the straight face, and even that smart-looking, cleanly formatted report might have a completely incorrect content.

theamk··on Anecdotally, programmers dislike "reduce"
I think your arguments would be much stronger with some actual code samples.

Usually, when the same code can be written either as range-based "for" or as a "while", the "for" will look better and have fewer possibility of bugs. If you have examples otherwise, I'd like to see them.

(Note I am specifically talking about range-based/iterator-based "for", not the C's variant. Nor am I talking the cases where the "for" is hard to use, like when the size might change at runtime)

theamk··on Anecdotally, programmers dislike "reduce"
you mean like that?

    todo_iter = iter(todo)
    while True:
        try:
            value = next(todo_iter)
        except StopIteration:
            break
        process(value)
or like that?

    todo_iter = iter(todo)  # Note: assume "todo" does not contain None
    while value := next(todo_iter, None):
        process(value)
I'd say neither of those are as clean as a simple for loop:

    for value in todo:
        process(value)
and yes, that's the case of a personal preference, although I'd bet a lot of Python programmers will share that preference with me. That's what "code smell" means, after all - it's not a bug which is clearly incorrect, it's a code which is best avoided based on reviewer's personal experience.
theamk··on Anecdotally, programmers dislike "reduce"
I assume OP refers to the cases where "while" is used to re-implement existing operations... imagine finding code like this:

     i = 0
     while i != len(todo):
         process(todo[i])
         i = i + 1
sure, there may be a good reason to implement things this way (maybe "todo" grows during iteration?), but maybe not, and then the loop should be instead simplified to:

     for value in todo:
         process(value)
(as an aside, this is exactly the case where the comments are required: "# not using for loop because todo might grow" will make it clear it's an intentional decision and not hallucination or something written from ignorance)
theamk··on PS5 Linux lead quits: "a bunch of noobs using LLMs" that "they don't understand"
I dunno, here is an entrant from 2025: https://news.ycombinator.com/item?id=45071024

(not a JS dev myself, but I read HN so I see those posts every once in a while..)

theamk··on Wikivibes – Write the encyclopedia you wished existed
This seems pretty useless. If you are making a wikipedia clone #10893, at least seed it with wikipedia content!
theamk··on NHTSA orders Tesla to prove its Cybercab is legal to sell, under oath
> The US doesn’t pre-approve vehicle designs. Automakers self-certify that their vehicles comply with all applicable Federal Motor Vehicle Safety Standards, and NHTSA checks after the fact.

huh, did not expect this. I wonder how many vehicles currently on road would fail those checks if the NHTSA started to pay close attention?

theamk··on Anecdotally, programmers dislike "reduce"
wow, TIL!

    Python 3.13.5 (main, Jul 15 2026, 20:25:40) [GCC 14.2.0] on linux
    >>> x = [[n]*1000 for n in range(1000)]; import timeit, itertools, functools, operator
    >>> timeit.timeit("len(list(sum(x, [])))", number=10, globals=globals())
    13.009033881127834
    >>> timeit.timeit("len(list(list(functools.reduce(operator.add, x, []))))", number=10, globals=globals())
    12.941937348805368
    >>> timeit.timeit("len(list(itertools.chain.from_iterable(x)))", number=10, globals=globals())
    0.0706032607704401
    >>> timeit.timeit("out=[]; [out.extend(i) for i in x]; len(out)", number=10, globals=globals())
    0.06334403157234192
    >>> timeit.timeit("len([i for a in x for i in a])", number=10, globals=globals())
    0.1232151910662651
mutable is fastest, itertools is just a bit slower, list comprehension is 2x slower, both "sum(..., [])" and "reduce" are 200 times slower!
theamk··on A 386 PC for Your RP2350
true, but the question was about "my currently running system (anno 2016)" - which means intel core most likely. And at that generation, there requirements for precise timing is extremely rare, it's mostly PCI/PCIe devices and they can be shared with VMs just fine.
theamk··on Anecdotally, programmers dislike "reduce"
At least in Python, I've found that "reduce" is very rarely needed. Most of the times, "sum" is enough, sometimes with "start" values customized (set it to [] to flatten an array for example). It is both easier to read, faster, and needs no imports. It also works great with list comprehensions - "sum(foo(x) for x in input if x > 5)" is much easier to read than reduce equivalent.

If you are multiplying, you are likely doing heavy math, and you'll be using numpy - which does not need reduce either.

If you are going to return a list of dict, then it's much faster to mutate the results, so using "reduce" will have significant performance implications (unless you want to return input argument, mis-using it as a glorified "for" loop)

And if returning not a list/dict, if you can use "min" or "max" or "any" or "all" or "next" (take the first element), then you should use it - it will be easier to read and faster too.

So what does this leave us for "reduce"? Frankly, not much. I've only seen it in merging immutable status codes, and that was pretty niche usecase to begin with.

(this was all for Python. In other languages without nice list of built-ins reduce might make more sense)

theamk··on A 386 PC for Your RP2350
Either "already" or "not any time soon", depending on how you count.

Already - because you have VMs and backwards compatibility. As long as you keep using Intel x86_64, your apps would run, no emulation needed. Or you can use the VM.

Not any time soon - because the computers are not speeding up that fast. 10 year old computers are still being used today, and even the latest CPUs are not orders of magnitude faster. So for a full-system emulation, the most well-known ones is x86 VM's on Apple Silicon, and according to reports, full-system mode is still not close to regular PCs.

theamk··on From Git to Fossil (2025)
There is something wrong with this explanation.

In the most common git setups, you never force-push to master - so a coworker can't rewrite history of master branch. Forges have protection rules, but even if your hosting does not, then the "git pull" will throw a ton of errors after history rewrites. So both fossil and git are similar in that regards.

On the other hand, unpushed branches can be rewritten any time in git.. but this applies to fossil as well. If you have not pushed your fossil changes, it's just a file on disk - you can delete it without pushing and no one will ever know you had intermediate version. Or work in "git" and only export to fossil (or svn or cvs or whatever) once things work.

theamk··on From Git to Fossil (2025)
This was CVS/SVN approach, and that's the reason git won so quickly (no, it was not github like some people claimed, I've seen git become popular in my circle before github was a thing)

I am not sure if you used CSV/SVN before - I did. It maintained the history of what was done in a very immutable way. The branches were heavy-weight and were only used for Serious Business, we generally had a person responsible for branching/merging. You only committed stuff which was in great shape and passed all the tests, just like Fossil wants you now.

And there were manual source code copying, so much copying.

- You are writing a feature and got interrupted mid-work to work on something else - copy/tar those files and restore from svn (you could also do a second checkout, but that destroys your cache).

- Want to send incomplete changes to friend? run "diff" and send them the patch by email, or place that patch file on shared disk.

- Your check-in failed, you need to merge in in latest changes from master? better tar up your work in case you break stuff.

- Are you doing new feature and want to see if refactor will improve it? don't forget to make a copy of changed files in case it does not.

None of this is worth committing on master. Who would want to share an incomplete feature which does not build / does not pass unit tests? Or an pre-refactor version of code which does not work?

Turns out using "git" covers all those usecases, and that's why it's the greatest thing. Fun fact: we've started using git in our team using git-svn, without central git server - we had mutable and shareable commits until the last moment, when we pushed it to central svn server.

IMHO, if you only want to record the final path code takes, and you plan to use "cp", "tar" and "patch" for throw-away work, then you might as well use a "releases" directory on FTP with timestamped archives. Why bother with VCS then?

theamk··on From Git to Fossil (2025)
14 "mistakes" in the entire 2025. I am probably making that many per week? Not to mention committing the intentionally broken stuff, with the expectation that I'll come back and amend if I decided it should go to main.
theamk··on From Git to Fossil (2025)
"Fossil purposely makes it difficult for users to delete content."

Those operations are explicitly declared special, not something you do many times per day because you had a typo in your print statement. I guess technically you can do it often, but the tooling does not make it easy at all, and you are going against program's recommended best practices.

theamk··on From Git to Fossil (2025)
What happens if you make a mistake while committing - maybe forget the file, or commit wrong one?

Fossil has no way to fix it, by design, and I find it an absolute showstopper. I do stupid mistakes all the time, and I am so glad that gits lets me fix those.

theamk··on Roon: "I think open source will be banned"
This talks about open source _AI models_, not open source software in general
theamk··on A Design Space Exploration of Async/Await
not sure what this has with my point?

I am not talking about "some language", I am talking about specific row in the table, "Python + Trio", which can be ABC or ACB depending on how exactly you implement the code.

For that matter, "Python + Asyncio" is a buggy code as well - if you actually try to run it, you'll get runtime warnings about tasks being garbage collected. Again, ideomatic code would be ACB as well.

theamk··on A Design Space Exploration of Async/Await
Very similar dimensions also apply to threads, the async/await is not really that different there.
theamk··on A Design Space Exploration of Async/Await
Linux has 8MB thread stacks by default, Windows apparently has 1MB ones, and that space is not going anywhere. As long as people are worried about memory, they will need something lighter than threads. (Yes, golang managed to create dynamic stacks, but this required major support from compiler and so unlikely to appear in existing languages).

Also, I think that single-threaded programs, even with co-routines, are just so much nicer than multi-threaded ones. You write "index = last_index++;" and it Just Works (tm), no need to worry about locks or atomics or other thread access.

theamk··on A Design Space Exploration of Async/Await
Great post, but the quiz is unfair - it assumes there is only one "true way", but a lot of frameworks give you options

For example, Trio has no global "spawn" method, by design. Judging by the results, authors assumed "with trio.open_nursery() as n: n.start_soon(write_to_log())", and so they got eager execution, dynamic extent, destructive propagation.

But opening a nursery just to write a single log line is absolutely crazy! The real program would use an appropriately scoped shared nursery: either per-request or global. Later option allows indefinite extent and "never" propagation.

Also, that "()" after write_to_log matters! If one follow trio's own examples, you'd write "n.start_soon(write_to_log)" - note no (). This will switch to lazy execution.

I am not familiar with non-python frameworks listed, but I would not be surprised if they allow for similarly wide range of behaviors.

theamk··on Proof of Capture: Apple Reference Image, but open source and using steganography
EXIF already includes extensive metadata, including phone model and GPS location. For professional cameras, there is often camera and lens serial numbers too.

This has been the case for many years, and so far social media sites never care - they strip that info instead. Why would this change with one more extra piece of metadata?

theamk··on Proof of Capture: Apple Reference Image, but open source and using steganography
If there is signed metadata too, then it's pretty hard. You will need to match focus distance (it will be very small if photographing picture), GPS location, exposure and other settings. If there is a depth map, you'll need to match it too.
theamk··on Proof of Capture: Apple Reference Image, but open source and using steganography
Yep, that breaks this scheme, making it useless. But it's far from the only thing making it useless, and the github page even explicitly lists those:

- "Small content edits slip under the threshold. [...] A localised edit covering ~15%x20% of the frame [...] passes as authentic" - this is the worst part. 15%x20% is huge, for example enough to change the face of the person or the book/text on the image.

- "Cropping is not survivable, at any amount" - given the purported reason for perceptual hashing is surviving light editing, it's pretty disappointing that one of the most common light editing operation is not supported.

Oh, and the whole "cryptographic chip" angle is absolutely bogus from the security perspective. OK, attacker can't extract the private key from chip. But they can simply connect the chip to a different device and have it sign anything! Given that the attacker in this model is device owner, this is absolutely trivial.

theamk··on Don't let anyone take away your big box of cables
Easy! I put exclusions on my labels

"USB cables, standard"

"USB passive/special, except pigtails and USB->AV"

"AV, including USB-AV cables"

theamk··on The Public Suffix List Is a Disaster
TL/DR: Ethereum nameserver provider applied to be in PSL, and had great trouble getting in, as it had dozens of malicious domains. They had to stop serving malicious domains to get in (the horrors!)

I can kinda see where the both parties come from.

On one side, browsers use PSL to harden security - by sandboxing sites, restricting shared cookies, etc.. a.example.com and b.example.com could share SameSite cookies and browser cache, but once added to PSL, they no longer can. Under that interpretation, it's strictly better to have PSL to be as large as possible, because the bigger the list is, the more secure the web is.

On other side, a lot of security-related tools use PSL to attribute bad behavior. For example if a.example.com is found to contain malware, a lot of services would mark entire "example.com" hierarchy as malicious, including "b.example.com"; but with PSL inclusion, it's only "a.example.com" which is suffering, while "example.com" itself and "b.example.com" having clean reputation.

That second use has an opposite effect - it actually decreases security of the web with each PSL entry. Every malware author would love to be on that list - "a123.malware.xyz" is marked malicious? No problem, switch to "a124.malware.xyz" which (thanks to PSL) is not burned yet. I am sure this is why getting on PSL list is so hard, and am I am sure that it's that isolation was the real motivation for author's effort, not "user security".

That said, I agree with author's 1st point - it would be nice to have official charter and governance structure for something as important as PSL.

But the 2nd point, "All PSL submissions are automatically merged after passing linter tests, without justification or further exposition."? Hell no. PSL should embrace being a security privilege it is, and behave accordingly. For example, if a DNS domain provider routinely serves malware and does not respond to the take-down requests, it should be kicked off the list. That one-off "no malware on subdomains" check should be automated and applied periodically to all PSL entries.

theamk··on Understanding the recent DDoS attack against Read the Docs
That's why GP mentioned "Smart TV".

A random Internet-connected smart plug made by KOCKJAKD and sold on Aliexpress? Almost impossible to catch.

A major brand like LG, with US presence and sold in brick-and-mortar stores? Much more possible. It also makes a much juicier target for lawyers, thus making it much more likely to get sued. And once there is a precedent, other manufactures would be in danger too. Hopefully after losing a whole bunch of money, the manufacturers will start cracking down on those residential proxies.

(Except that discovery is going to be painful. "Use discovery to find out what's on the other end" is easy to write, but in practice it means regular people dealing with bailiffs just because they happen to buy wrong brand of smart TV)

theamk··on I resigned from Anthropic today
Those drones can only stay up for a few hours at most. Then they need refueling and relaunch, with plenty of human-only steps.

Even if you have terminator-style AI uprising, all you need to do to be safe from those drones is to wait a day.

(The automated weapons can probably last longer, but they still need electricity, and there are still a lot of human steps there)

← PreviousPage 2 of 34Next →